#include <ctime>
int main(int argc, char *argv[])
{
std::string geometry("domain2d/yeti_mp2.xml");
real_t stretchGeometry = 1;
std::string boundaryConditions("d");
real_t tolerance = 1.e-8;
std::string out;
bool plot = false;
gsCmdLine cmd(
"Solves a PDE with an isogeometric discretization using an isogeometric tearing and interconnecting (IETI) solver.");
cmd.addString("g", "Geometry", "Geometry file", geometry);
cmd.addInt ("", "SplitPatches", "Split every patch that many times in 2^d patches", splitPatches);
cmd.addReal ("", "StretchGeometry", "Stretch geometry in x-direction by the given factor", stretchGeometry);
cmd.addInt ("r", "Refinements", "Number of uniform h-refinement steps to perform before solving", refinements);
cmd.addInt ("p", "Degree", "Degree of the B-spline discretization space", degree);
cmd.addString("b", "BoundaryConditions", "Boundary conditions", boundaryConditions);
cmd.addReal ("t", "Solver.Tolerance", "Stopping criterion for linear solver", tolerance);
cmd.addInt ("", "Solver.MaxIterations", "Stopping criterion for linear solver", maxIterations);
cmd.addString("", "out", "Write solution and used options to file", out);
cmd.addSwitch( "plot", "Plot the result with Paraview", plot);
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
{
gsInfo <<
"Geometry file could not be found.\n";
return EXIT_FAILURE;
}
gsInfo <<
"Run ieti_example with options:\n" << cmd << std::endl;
gsInfo <<
"Define geometry... " << std::flush;
if (!mpPtr)
{
gsInfo <<
"No geometry found in file " << geometry <<
".\n";
return EXIT_FAILURE;
}
for (
index_t i=0; i<splitPatches; ++i)
{
gsInfo <<
"split patches uniformly... " << std::flush;
mp = mp.uniformSplit();
}
if (stretchGeometry!=1)
{
gsInfo <<
"and stretch it... " << std::flush;
for (size_t i=0; i!=mp.nPatches(); ++i)
}
gsInfo <<
"Define right-hand-side and boundary conditions... " << std::flush;
{
const index_t len = boundaryConditions.length();
for (gsMultiPatch<>::const_biterator it = mp.bBegin(); it < mp.bEnd(); ++it)
{
char b_local;
if ( len == 1 )
b_local = boundaryConditions[0];
else if ( i < len )
b_local = boundaryConditions[i];
else
{
gsInfo <<
"\nNot enough boundary conditions given.\n";
return EXIT_FAILURE;
}
if ( b_local == 'd' )
else if ( b_local == 'n' )
else
{
gsInfo <<
"\nInvalid boundary condition given; only 'd' (Dirichlet) and 'n' (Neumann) are supported.\n";
return EXIT_FAILURE;
}
++i;
}
if ( len > i )
gsInfo <<
"\nToo many boundary conditions have been specified. Ignoring the remaining ones.\n";
gsInfo <<
"done. "<<i<<
" boundary conditions set.\n";
}
gsInfo <<
"Setup bases and adjust degree... " << std::flush;
for ( size_t i = 0; i < mb.nBases(); ++ i )
mb[i].setDegreePreservingMultiplicity(degree);
for (
index_t i = 0; i < refinements; ++i )
mb.uniformRefine();
gsInfo <<
"Setup assembler and assemble matrix... " << std::flush;
const index_t nPatches = mp.nPatches();
{
mp,
mb,
bc,
f,
dirichlet::elimination,
iFace::glue
);
assembler.computeDirichletDofs();
ietiMapper.
init( mb, assembler.system().rowMapper(0), assembler.fixedDofs() );
}
bool fullyRedundant = true,
noLagrangeMultipliersForCorners = true;
{
mp_local,
mb_local,
bc_local,
f,
dirichlet::elimination,
iFace::glue
);
assembler.setFixedDofVector(ietiMapper.
fixedPart(k));
assembler.assemble();
std::vector<index_t> skeletonDofs = ietiMapper.
skeletonDofs(k);
);
const bool eliminatePointwiseDofs = true;
eliminatePointwiseDofs,
localMatrix,
modifiedLocalMatrix,
localEmbedding,
embeddingForBasis,
rhsForBasis
);
primal.addContribution(
jumpMatrix, localMatrix, localRhs,
localSolver, embeddingForBasis, rhsForBasis, ietiMapper.
primalDofIndices(k), primal.nPrimalDofs()
)
);
gsMatrix<> modifiedLocalRhs = localEmbedding.transpose() * localRhs;
bdPrec->addOperator(k,k,localSolver);
makeMatrixOp(modifiedLocalMatrix.
moveToPtr()),
);
}
{
bdPrec->addOperator(nPatches, nPatches, makeSparseCholeskySolver(primal.localMatrix()));
primal.jumpMatrix().moveToPtr(),
makeMatrixOp(primal.localMatrix().moveToPtr()),
);
}
gsInfo <<
"Setup solver and solve... \n"
" Setup multiplicity scaling... " << std::flush;
bdPrec->addOperator(bdPrecSz-1,bdPrecSz-1,sdPrec);
gsInfo <<
"done.\n Setup minres solver and solve... " << std::flush;
x.setRandom( bdPrec->rows(), 1 );
gsInfo <<
"done.\n Reconstruct solution from Lagrange multipliers... " << std::flush;
std::vector<gsMatrix<>> uLocal = primal.distributePrimalSolution(
);
const index_t iter = errorHistory.rows()-1;
const bool success = errorHistory(iter,0) < tolerance;
if (success)
gsInfo <<
"Reached desired tolerance after " << iter <<
" iterations:\n";
else
gsInfo <<
"Did not reach desired tolerance after " << iter <<
" iterations:\n";
if (errorHistory.rows() < 20)
gsInfo << errorHistory.transpose() <<
"\n\n";
else
gsInfo << errorHistory.topRows(5).transpose() <<
" ... " << errorHistory.bottomRows(5).transpose() <<
"\n\n";
if (!out.empty())
{
std::time_t time = std::time(NULL);
fd.add(cmd);
fd.add(uGlobal);
fd.addComment(std::string("ieti2_example Timestamp:")+std::ctime(&time));
fd.save(out);
gsInfo <<
"Write solution to file " << out <<
"\n";
}
if (plot)
{
gsInfo <<
"Write Paraview data to file ieti_result.pvd\n";
gsWriteParaview<>(
gsField<>( mp, mpsol ),
"ieti_result", 1000);
}
if (!plot&&out.empty())
{
gsInfo <<
"Done. No output created, re-run with --plot to get a ParaView "
"file containing the solution or --out to write solution to xml file.\n";
}
return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
static uPtr make(index_t nRows, index_t nCols)
Make function returning a smart pointer.
Definition gsBlockOp.h:60
memory::shared_ptr< gsBlockOp< T > > Ptr
Shared pointer for gsBlockOp.
Definition gsBlockOp.h:48
Class containing a set of boundary conditions.
Definition gsBoundaryConditions.h:342
void getConditionsForPatch(const index_t np, gsBoundaryConditions &result) const
returns the set of all boundary conditions which refer to patch np
Definition gsBoundaryConditions.h:848
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
Class defining a globally constant function.
Definition gsConstantFunction.h:34
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
A scalar of vector field defined on a m_parametric geometry.
Definition gsField.h:55
This class represents an XML data tree which can be read from or written to a (file) stream.
Definition gsFileData.h:34
static std::string getSearchPaths()
Get the defined search paths.
Definition gsFileManager.cpp:271
static bool fileExists(const std::string &name)
Checks if the file exists.
Definition gsFileManager.cpp:62
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
void scale(T s, int coord=-1)
Apply Scaling by factor s.
Definition gsGeometry.h:413
Ieti Mapper.
Definition gsIetiMapper.h:50
Matrix incorporateFixedPart(index_t k, const gsMatrix< T > &localSolution) const
Incorporates fixedPart (eg. from eliminated Dirichlet dofs) to given patch-local solution.
Definition gsIetiMapper.hpp:400
void computeJumpMatrices(bool fullyRedundant, bool excludeCorners)
This function computes the jump matrices.
Definition gsIetiMapper.hpp:297
const Matrix & fixedPart(index_t k) const
The function values for the eliminated dofs on the given patch Only available after computeJumpMatric...
Definition gsIetiMapper.h:179
void cornersAsPrimals()
Set up the corners as primal dofs.
Definition gsIetiMapper.hpp:126
const gsDofMapper & dofMapperLocal(index_t k) const
The dof mapper for the given patch Only available after computeJumpMatrices has been called.
Definition gsIetiMapper.h:175
void init(const gsMultiBasis< T > &multiBasis, gsDofMapper dofMapperGlobal, const Matrix &fixedPart)
Init the ieti mapper after default construction.
Definition gsIetiMapper.hpp:30
Matrix constructGlobalSolutionFromLocalSolutions(const std::vector< Matrix > &localContribs)
Construct the global solution from a vector of patch-local ones.
Definition gsIetiMapper.hpp:91
const std::vector< index_t > & primalDofIndices(index_t k) const
Returns the indices of the primal dofs that are associated to the primal constraints for the given pa...
Definition gsIetiMapper.h:164
index_t nPrimalDofs() const
Returns the size of the primal problem (number of primal dofs)
Definition gsIetiMapper.h:154
std::vector< index_t > skeletonDofs(index_t patch) const
Returns a list of dofs that are (on the coarse level) coupled.
Definition gsIetiMapper.hpp:282
const JumpMatrix & jumpMatrix(index_t k) const
Returns the jump matrix for the given patch Only available after computeJumpMatrices has been called...
Definition gsIetiMapper.h:168
const std::vector< SparseVector > & primalConstraints(index_t k) const
Returns the primalConstraints (as vectors) for the given patch.
Definition gsIetiMapper.h:160
This class represents a IETI system.
Definition gsIetiSystem.h:70
OpPtr saddlePointProblem() const
Returns gsLinearOperator that represents the IETI problem as saddle point problem.
Definition gsIetiSystem.hpp:68
void addSubdomain(JumpMatrixPtr jumpMatrix, OpPtr localMatrixOp, Matrix localRhs, OpPtr localSolverOp=OpPtr())
Definition gsIetiSystem.hpp:32
std::vector< Matrix > constructSolutionFromSaddlePoint(const Matrix &x) const
Returns the local solutions for the individual subdomains.
Definition gsIetiSystem.hpp:141
void reserve(index_t n)
Reserves the memory required to store the number of subdomains.
Definition gsIetiSystem.hpp:23
Matrix rhsForSaddlePoint() const
Returns the right-hand-side that is required for the saddle point formulation of the IETI problem.
Definition gsIetiSystem.hpp:122
void solveDetailed(const VectorType &rhs, VectorType &x, VectorType &error_history)
Solves the linear system and stores the solution in x and records the error histroy.
Definition gsIterativeSolver.h:134
memory::shared_ptr< gsLinearOperator > Ptr
Shared pointer for gsLinearOperator.
Definition gsLinearOperator.h:33
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
The minimal residual (MinRes) method.
Definition gsMinimalResidual.h:26
gsMinimalResidual & setOptions(const gsOptionList &opt)
Set the options based on a gsOptionList.
Definition gsMinimalResidual.h:71
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
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition gsMultiPatch.hpp:211
memory::unique_ptr< gsMultiPatch > uPtr
Unique pointer for gsMultiPatch.
Definition gsMultiPatch.h:109
Implementation of an (multiple right-hand side) Poisson assembler.
Definition gsPoissonAssembler.h:37
This class represents the primal system for a IETI-DP algorithm.
Definition gsPrimalSystem.h:87
static void incorporateConstraints(const std::vector< SparseVector > &primalConstraints, bool eliminatePointwiseConstraints, const SparseMatrix &localMatrix, SparseMatrix &modifiedLocalMatrix, SparseMatrix &localEmbedding, SparseMatrix &embeddingForBasis, Matrix &rhsForBasis)
Incorporates the given constraints in the local system.
Definition gsPrimalSystem.hpp:27
Reads an object from a data file, if such the requested object exists in the file.
Definition gsReadFile.h:43
This class represents the scaled Dirichlet preconditioner for a IETI problem.
Definition gsScaledDirichletPrec.h:79
OpPtr preconditioner() const
This returns the preconditioner as gsLinearOperator.
Definition gsScaledDirichletPrec.hpp:176
void addSubdomain(JumpMatrixPtr jumpMatrix, OpPtr localSchurOp)
Definition gsScaledDirichletPrec.h:107
void reserve(index_t n)
Reserves the memory required to store the given number of subdomain.
Definition gsScaledDirichletPrec.h:90
static JumpMatrix restrictJumpMatrix(const JumpMatrix &jumpMatrix, const std::vector< index_t > &dofs)
Restricts the jump matrix to the given dofs.
Definition gsScaledDirichletPrec.hpp:36
void setupMultiplicityScaling()
This sets up the member vector localScaling based on multiplicity scaling.
Definition gsScaledDirichletPrec.hpp:149
static Blocks matrixBlocks(const SparseMatrix &localMatrix, const std::vector< index_t > &dofs)
Computes the matrix blocks with respect to the given dofs.
Definition gsScaledDirichletPrec.hpp:64
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
uPtr moveToPtr()
This function returns a smart pointer to the matrix. After calling it, the matrix object becomes empt...
Definition gsSparseMatrix.h:247
A sparse linear system indexed by sets of degrees of freedom.
Definition gsSparseSystem.h:30
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.
S give(S &x)
Definition gsMemory.h:266
@ dirichlet
Dirichlet type.
Definition gsBoundaryConditions.h:31
@ neumann
Neumann type.
Definition gsBoundaryConditions.h:33
Definition gsScaledDirichletPrec.h:148