#include <ctime>
using namespace gismo;
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;
}
if (stretchGeometry!=1)
{
gsInfo << "and stretch it... " << std::flush;
}
gsInfo << "done.\n";
gsInfo << "Define right-hand-side and boundary conditions... " << std::flush;
{
const index_t len = boundaryConditions.length();
{
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 )
gsInfo << "done.\n";
gsInfo << "Setup assembler and assemble matrix... " << std::flush;
{
mp,
mb,
bc,
f,
dirichlet::elimination,
iFace::glue
);
assembler.computeDirichletDofs();
ietiMapper.
init( mb, assembler.system().rowMapper(0), assembler.fixedDofs() );
}
bool fullyRedundant = true,
noLagrangeMultipliersForCorners = true;
{
bc.getConditionsForPatch(k,bc_local);
mp_local,
mb_local,
bc_local,
f,
dirichlet::elimination,
iFace::glue
);
assembler.setFixedDofVector(ietiMapper.
fixedPart(k));
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 << "done.\n";
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 );
.setOptions( cmd.getGroup("Solver") )
gsInfo << "done.\n Reconstruct solution from Lagrange multipliers... " << std::flush;
std::vector<gsMatrix<>> uLocal = primal.distributePrimalSolution(
);
gsInfo << "done.\n\n";
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.addComment(std::string("ieti2_example Timestamp:")+std::ctime(&time));
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;
}