G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
poissonTHB_example.cpp

More details on the hierarchical splines can be found in thbSplineBasis_example.cpp, adaptRefinementThb_example.cpp as well as in the Hierarchical splines module description.

Annotated source file

Here is the full file examples/poissonTHB_example.cpp. Clicking on a function or class name will lead you to its reference documentation.

#include <gismo.h>
using namespace gismo;
//S.Kleiss
//
//This is a test example for a illustrating the adaptive
//refinement procedure implemented in the gsPoissonAssembler
//
//Flags, parameters, geometry and prescribed exact solution
//are specified within the main() function
int main(int argc, char *argv[])
{
// Number of initial uniform mesh refinements
index_t initUnifRef;
// Number of adaptive refinement loops
index_t RefineLoopMax;
// Flag for refinemet criterion
// (see doxygen documentation of the free function
// gsMarkElementsForRef explanation)
index_t refCriterion; // MarkingStrategy
// Parameter for computing adaptive refinement threshold
// (see doxygen documentation of the free function
// gsMarkElementsForRef explanation)
real_t refParameter; // ...specified below with the examples
// Degree to use for discretization
index_t degree;
// Flag whether final mesh should be plotted in ParaView
bool plot = false;
bool manual = false;
bool HB = false;
bool dump;
RefineLoopMax = 2;
initUnifRef = 2;
degree = 2;
refCriterion = PUCA;
refParameter = 0.85;
dump = false;
index_t refExt = 0;
gsCmdLine cmd("Solving a PDE with adaptive refinement using THB-splines.");
cmd.addSwitch("plot", "Plot resulting mesh in ParaView", plot);
cmd.addInt("r", "refine", "Maximum number of adaptive refinement steps to perform",
RefineLoopMax);
cmd.addInt("i", "initial-ref", "Initial number of uniform refinement steps to perform",
initUnifRef);
cmd.addInt("", "degree", "Spline degree of the THB basis", degree);
cmd.addInt("c", "criterion", "Criterion to be used for adaptive refinement (1-3, see documentation)",
refCriterion);
cmd.addInt("E", "extension", "Criterion to be used for adaptive refinement (1-3, see documentation)",
refExt);
cmd.addReal("p", "parameter", "Parameter for adaptive refinement", refParameter);
cmd.addSwitch("dump", "Write geometry and sequence of bases into XML files",
dump);
cmd.addSwitch("manual", "Uses the 'addLevel' feature of the THB basis, where levels can be specified manually", manual);
cmd.addSwitch("HB", "Uses a Hierarchical basis instead of a Truncated Hierarchical basis", HB);
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
// ****** Prepared test examples ******
//
// f ... source term
// g ... exact solution
// patches ... the computational domain given as object of gsMultiPatch
//
// ------ Example 1 ------
// --- Unit square, with a spike of the source function at (0.25, 0.6)
gsFunctionExpr<> f("if( (x-0.25)^2 + (y-0.6)^2 < 0.2^2, 1, 0 )",2);
//gsFunctionExpr<> f("if( (x-0.25)^2 + (y-1.6)^2 < 0.2^2, 1, 0 )",2);
gsFunctionExpr<> g("0",2);
gsMultiPatch<> patches( *gsNurbsCreator<>::BSplineRectangle(0.0,0.0,2.0,1.0) );
//gsMultiPatch<> patches( *gsNurbsCreator<>::BSplineFatQuarterAnnulus(1.0, 2.0) );
//RefineLoopMax = 6;
//refParameter = 0.6;
// ^^^^^^ Example 1 ^^^^^^
/*
// ------ Example 2 ------
// The classical example associated with the L-Shaped domain.
// The exact solution has a singularity at the re-entrant corner at the origin.
gsFunctionExpr<> f("0",2);
gsFunctionExpr<> g("if( y>0, ( (x^2+y^2)^(1.0/3.0) )*sin( (2*atan2(y,x) - pi)/3.0 ), ( (x^2+y^2)^(1.0/3.0) )*sin( (2*atan2(y,x) +3*pi)/3.0 ) )",2);
//gsMultiPatch<> patches (*gsNurbsCreator<>::BSplineLShape_p2C0());
gsMultiPatch<> patches (*gsNurbsCreator<>::BSplineLShape_p1());
//RefineLoopMax = 8;
//refParameter = 0.85;
// ^^^^^^ Example 2 ^^^^^^
*/
gsInfo<<"Source function "<< f << "\n";
gsInfo<<"Exact solution "<< g <<".\n" << "\n";
// Define Boundary conditions
// Dirichlet BCs
bcInfo.addCondition( boundary::west, condition_type::dirichlet, &g );
bcInfo.addCondition( boundary::east, condition_type::dirichlet, &g );
bcInfo.addCondition( boundary::north, condition_type::dirichlet, &g );
bcInfo.addCondition( boundary::south, condition_type::dirichlet, &g );
gsTensorBSpline<2,real_t> * geo = dynamic_cast< gsTensorBSpline<2,real_t> * >( & patches.patch(0) );
gsInfo << " --- Geometry:\n" << *geo << "\n";
gsInfo << "Number of patches: " << patches.nPatches() << "\n";
if (dump)
gsWrite(*geo, "adapt_geo.xml");
tbb.setDegree(degree);
gsInfo << "\nCoarse discretization basis:\n" << tbb << "\n";
// With this gsTensorBSplineBasis, it's possible to call the THB-Spline constructor
for (int i = 0; i < initUnifRef; ++i)
{
if (manual)
tbb.uniformRefine(1,1);
else
tbb.uniformRefine();
}
if (manual)
{
// Manual creation of levels in THB hierarchy
// We create a hierarchy where in the first degree levels, the basis is refined and the continuity is reduced
// Then diadic refinements are created
// lvl 0: {0, 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1, 1}
// lvl 1: {0, 0, 0, 0, 0.125, 0.125, 0.25, 0.25, 0.375, 0.375, 0.5, 0.5, 0.625, 0.625, 0.75, 0.75, 0.825, 0.825, 1, 1, 1, 1}
// lvl 2: {0, 0, 0, 0, 0.0625, 0.0625, 0.0625, 0.125, 0.125, 0.125, ...}
// lvl 3: {0, 0, 0, 0, 0.0625, 0.0625, 0.0625, 0.125, 0.125, 0.125, ...}
// etc
if (HB)
HTB = new gsHBSplineBasis<2,real_t>(tbb,true);
else
HTB = new gsTHBSplineBasis<2,real_t>(tbb,true);
for (index_t k=0; k!=degree-2; k++)
{
tbb.uniformRefine(1,k+1);
tbb.reduceContinuity(1);
tbb.removeKnot(0.5,0,1);
HTB->addLevel(tbb);
}
for (index_t k=0; k!=5; k++)
{
tbb.uniformRefine(1,degree-1);
HTB->addLevel(tbb);
}
// This works
//{
// for (index_t k=0; k!=3; k++)
// {
// tbb.uniformRefine(1,2);
// gsDebugVar(gsAsConstVector<index_t>(tbb.knots(0).multiplicities()));
// gsDebugVar(tbb.knots(0).asMatrix());
// HTB->addLevel(tbb);
// }
//}
HTB->printBases();
}
else
{
if (HB)
HTB = new gsHBSplineBasis<2,real_t>(tbb,false);
else
HTB = new gsTHBSplineBasis<2,real_t>(tbb,false);
}
gsMatrix<> boxes(2,2);
boxes.row(0)<<0.25,0.75;
boxes.row(1)<<0.00,1.00;
HTB->refine(boxes);
// Finally, create a vector (of length one) of this gsTHBSplineBasis
gsMultiBasis<real_t> bases(*HTB);
gsMultiPatch<> mpsol; // holds computed solution
gsPoissonAssembler<real_t> pa(patches,bases,bcInfo,f);// constructs matrix and rhs
pa.options().setInt("DirichletValues", dirichlet::l2Projection);
if (dump)
gsWrite(bases[0], "adapt_basis_0.xml");
// So, ready to start the adaptive refinement loop:
for( int RefineLoop = 1; RefineLoop <= RefineLoopMax ; RefineLoop++ )
{
gsInfo << "\n============================== Loop " << RefineLoop << " of " << RefineLoopMax << " ==============================" << "\n" << "\n";
gsHTensorBasis<2,real_t> * HTB_tmp = dynamic_cast<gsHTensorBasis<2,real_t> * >(&pa.multiBasis().basis(0));
bool unity = HTB_tmp->testPartitionOfUnity();
std::string unity_string = unity ? "has " : "does not have ";
gsInfo<<" * Number of elements: "<<HTB_tmp->numElements()<<"\n";
gsInfo<<" * Maximum level: "<<HTB_tmp->maxLevel()+1<<"\n";
gsInfo<<" * Tree size: "<<HTB_tmp->treeSize()<<"\n";
gsInfo<<" * Number of functions: "<<HTB_tmp->size()<<"\n";
gsInfo<<" * Size per level: ";
for(unsigned i = 0; i<= HTB_tmp->maxLevel(); i++)
gsInfo << HTB_tmp->getXmatrix()[i].size()<< " ";
gsInfo<<"\n";
gsInfo<<" * Partition of unity: The basis "<<unity_string<<"the partition of unity property\n";
gsInfo<<"=========================================================================\n";
// Assemble matrix and rhs
gsInfo << "Assembling... " << std::flush;
pa.assemble();
gsInfo << "done." << "\n";
// Solve system
gsInfo << "Solving... " << std::flush;
gsMatrix<> solVector = gsSparseSolver<>::CGDiagonal(pa.matrix() ).solve( pa.rhs() );
gsInfo << "done." << "\n";
// Construct the solution for plotting the mesh later
pa.constructSolution(solVector, mpsol);
gsField<> sol(pa.patches(), mpsol);
// Set up and compute the L2-error to the known exact solution...
ev.setIntegrationElements(pa.multiBasis());
gsExprEvaluator<>::geometryMap Gm = ev.getMap(patches);
auto ff = ev.getVariable(f, Gm);
// The vector with element-wise local error estimates.
ev.integralElWise( (ilapl(f1,Gm) + ff).sqNorm() * meas(Gm) );
const std::vector<real_t> & elErrEst = ev.elementwise();
// Get the vector with element-wise local (known in this case) errors...
//gsExprEvaluator<>::variable gg = ev.getVariable(g, Gm);
//ev.integralElWise( (f1 - gg).sqNorm() * meas(Gm) );
//const std::vector<real_t> & elErrEst = ev.elementwise();
// Mark elements for refinement, based on the computed local errors and
// refCriterion and refParameter.
std::vector<bool> elMarked( elErrEst.size() );
gsMarkElementsForRef( elErrEst, refCriterion, refParameter, elMarked);
gsInfo <<"Marked "<< std::count(elMarked.begin(), elMarked.end(), true)<<"\n";
// Refine the elements of the mesh, based on elMarked.
gsRefineMarkedElements( pa.multiBasis(), elMarked, refExt);
// Refresh the assembler, since basis is now changed
pa.refresh();
if (dump)
{
std::stringstream ss;
ss << "adapt_basis_" << RefineLoop << ".xml";
gsWrite(pa.multiBasis()[0], ss.str());
}
if ( (RefineLoop == RefineLoopMax) && plot)
{
// Write approximate solution to paraview files
gsInfo<<"Plotting in Paraview...\n";
gsWriteParaview<>(sol, "p2d_adaRef_sol", 5001, true);
gsWriteParaview<>(pa.multiBasis()[0], "basis", 500, true);
// Run paraview and plot the last mesh
gsFileManager::open("p2d_adaRef_sol.pvd");
}
}
gsInfo << "\nFinal basis: " << pa.multiBasis()[0] << "\n";
delete HTB;
return EXIT_SUCCESS;
}
Definition gsExpressions.h:928
void setDegree(short_t const &i)
Set the degree of the basis (either elevate or reduce) in order to have degree equal to i wrt to each...
Definition gsBasis.hpp:645
Class containing a set of boundary conditions.
Definition gsBoundaryConditions.h:342
void addCondition(int p, boxSide s, condition_type::type t, gsFunctionSet< T > *f, short_t unknown=0, bool parametric=false, int comp=-1)
Adds another boundary condition.
Definition gsBoundaryConditions.h:650
Class for command-line argument parsing.
Definition gsCmdLine.h:57
Generic evaluator of isogeometric expressions.
Definition gsExprEvaluator.h:39
void setIntegrationElements(const gsMultiBasis< T > &mesh)
Sets the domain of integration.
Definition gsExprEvaluator.h:110
const std::vector< T > & elementwise() const
Returns an std::vector containing the last computed values per element.
Definition gsExprEvaluator.h:99
T integralElWise(const expr::_expr< E > &expr)
Calculates the integral of the expression expr on each element.
Definition gsExprEvaluator.h:159
variable getVariable(const gsFunctionSet< T > &func, index_t dim=1)
Registers func as a variable and returns a handle to it.
Definition gsExprEvaluator.h:124
geometryMap getMap(const gsMultiPatch< T > &mp)
Registers mp as an isogeometric geometry map and return a handle to it.
Definition gsExprEvaluator.h:116
A scalar of vector field defined on a m_parametric geometry.
Definition gsField.h:55
static void open(const std::string &fn)
Opens the file fn using the preferred application of the OS.
Definition gsFileManager.cpp:688
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
A hierarchical B-spline basis of parametric dimension d.
Definition gsHBSplineBasis.h:36
Class representing a (scalar) hierarchical tensor basis of functions .
Definition gsHTensorBasis.h:75
int treeSize() const
The number of nodes in the tree representation.
Definition gsHTensorBasis.h:647
virtual void refine(gsMatrix< T > const &boxes, int refExt)
Refine the basis to levels and in the areas defined by boxes with an extension.
Definition gsHTensorBasis.hpp:445
void printBases(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition gsHTensorBasis.h:542
void addLevel(const gsTensorBSplineBasis< d, T > &next_basis)
Adds a level, only if manual levels are activated.
Definition gsHTensorBasis.hpp:35
index_t size() const
The number of basis functions in this basis.
Definition gsHTensorBasis.hpp:298
bool testPartitionOfUnity(const index_t npts=100, const T tol=1e-12) const
Test the partition of unity.
Definition gsHTensorBasis.hpp:1972
unsigned maxLevel() const
Returns the level in which the indices are stored internally.
Definition gsHTensorBasis.h:811
size_t numElements(boxSide const &s=0) const
The number of elements on side s.
Definition gsHTensorBasis.h:972
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
Implementation of an (multiple right-hand side) Poisson assembler.
Definition gsPoissonAssembler.h:37
Truncated hierarchical B-spline basis.
Definition gsTHBSplineBasis.h:36
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition gsTensorBSpline.h:45
Main header to be included by clients using the G+Smo library.
void gsMarkElementsForRef(const std::vector< T > &elError, int refCriterion, T refParameter, std::vector< bool > &elMarked)
Marks elements/cells for refinement.
Definition gsAdaptiveRefUtils.h:196
void gsRefineMarkedElements(gsMultiBasis< T > &basis, const std::vector< bool > &elMarked, index_t refExtension=0)
Refine a gsMultiBasis, based on a vector of element-markings.
Definition gsAdaptiveRefUtils.h:294
Provides class for adaptive refinement.
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
EIGEN_STRONG_INLINE meas_expr< T > meas(const gsGeometryMap< T > &G)
The measure of a geometry map.
Definition gsExpressions.h:4555
The G+Smo namespace, containing all definitions for the library.
void gsWrite(const Object &obj, const std::string &fname)
Write an arbitrary Gismo object to an XML file with the given filename.
Definition gsReadFile.h:288
@ dirichlet
Dirichlet type.
Definition gsBoundaryConditions.h:31
Class gsNurbsCreator provides some simple examples of Nurbs Geometries.
Definition gsNurbsCreator.h:37