Skip to content

Commit

Permalink
Nullspace/rigid body modes tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
ddemidov committed Dec 1, 2020
1 parent 8d8217b commit 3a1d5bc
Show file tree
Hide file tree
Showing 8 changed files with 568 additions and 0 deletions.
447 changes: 447 additions & 0 deletions docs/Nullspace.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ GeForce GTX 1050 Ti GPU.
SerenaMPI
CoupCons3D
Stokes
Nullspace
3 changes: 3 additions & 0 deletions tutorial/5.Nullspace/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_executable(nullspace nullspace.cpp)
target_link_libraries(nullspace amgcl)

Binary file added tutorial/5.Nullspace/displacements.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorial/5.Nullspace/matrix.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 changes: 93 additions & 0 deletions tutorial/5.Nullspace/nullspace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <vector>
#include <iostream>

#include <amgcl/backend/builtin.hpp>
#include <amgcl/adapter/crs_tuple.hpp>
#include <amgcl/make_solver.hpp>
#include <amgcl/amg.hpp>
#include <amgcl/coarsening/smoothed_aggregation.hpp>
#include <amgcl/coarsening/rigid_body_modes.hpp>
#include <amgcl/relaxation/spai0.hpp>
#include <amgcl/solver/cg.hpp>

#include <amgcl/io/mm.hpp>
#include <amgcl/profiler.hpp>

int main(int argc, char *argv[]) {
// The command line should contain the matrix, the RHS, and the coordinate files:
if (argc < 4) {
std::cerr << "Usage: " << argv[0] << " <A.mtx> <b.mtx> <coo.mtx>" << std::endl;
return 1;
}

// The profiler:
amgcl::profiler<> prof("Nullspace");

// Read the system matrix, the RHS, and the coordinates:
ptrdiff_t rows, cols, ndim, ncoo;
std::vector<ptrdiff_t> ptr, col;
std::vector<double> val, rhs, coo;

prof.tic("read");
std::tie(rows, rows) = amgcl::io::mm_reader(argv[1])(ptr, col, val);
std::tie(rows, cols) = amgcl::io::mm_reader(argv[2])(rhs);
std::tie(ncoo, ndim) = amgcl::io::mm_reader(argv[3])(coo);
prof.toc("read");

amgcl::precondition(ncoo * ndim == rows && (ndim == 2 || ndim == 3),
"The coordinate file has wrong dimensions");

std::cout << "Matrix " << argv[1] << ": " << rows << "x" << rows << std::endl;
std::cout << "RHS " << argv[2] << ": " << rows << "x" << cols << std::endl;
std::cout << "Coords " << argv[3] << ": " << ncoo << "x" << ndim << std::endl;

// Declare the solver type
typedef amgcl::backend::builtin<double> SBackend; // the solver backend
typedef amgcl::backend::builtin<float> PBackend; // the preconditioner backend

typedef amgcl::make_solver<
amgcl::amg<
PBackend,
amgcl::coarsening::smoothed_aggregation,
amgcl::relaxation::spai0
>,
amgcl::solver::cg<SBackend>
> Solver;

// Solver parameters:
Solver::params prm;
prm.precond.coarsening.aggr.eps_strong = 0;

// Convert the coordinates to the rigid body modes.
// The function returns the number of near null-space vectors
// (3 in 2D case, 6 in 3D case) and writes the vectors to the
// std::vector<double> specified as the last argument:
prm.precond.coarsening.nullspace.cols = amgcl::coarsening::rigid_body_modes(
ndim, coo, prm.precond.coarsening.nullspace.B);

// We use the tuple of CRS arrays to represent the system matrix.
auto A = std::tie(rows, ptr, col, val);

// Initialize the solver with the system matrix.
prof.tic("setup");
Solver solve(A, prm);
prof.toc("setup");

// Show the mini-report on the constructed solver:
std::cout << solve << std::endl;

// Solve the system with the zero initial approximation:
int iters;
double error;
std::vector<double> x(rows, 0.0);

prof.tic("solve");
std::tie(iters, error) = solve(A, rhs, x);
prof.toc("solve");

// Output the number of iterations, the relative error,
// and the profiling data:
std::cout << "Iters: " << iters << std::endl
<< "Error: " << error << std::endl
<< prof << std::endl;
}
23 changes: 23 additions & 0 deletions tutorial/5.Nullspace/plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python
from pylab import *
from scipy.io import mmread

A = mmread('A.mtx')

fig, (ax1, ax2) = subplots(2, 1, sharex=True, figsize=(8,10), gridspec_kw=dict(height_ratios=[4,1]))
ax1.spy(A, marker='.', markersize=0.25, alpha=0.2)
axins = ax1.inset_axes([0.55, 0.55, 0.3, 0.3])
axins.spy(A, marker='o', markersize=3, alpha=0.5)
n = 39880
axins.set_xlim([n - 0.5, n + 60.5])
axins.set_ylim([n - 0.5, n + 60.5])
axins.invert_yaxis()
axins.set_xticklabels('')
axins.set_yticklabels('')
ax1.indicate_inset_zoom(axins)

ax2.semilogy(A.diagonal())
ax2.set_ylabel('Diagonal')

tight_layout()
savefig('matrix.png')
1 change: 1 addition & 0 deletions tutorial/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ add_subdirectory(1.poisson3Db)
add_subdirectory(2.Serena)
add_subdirectory(3.CoupCons3D)
add_subdirectory(4.Stokes)
add_subdirectory(5.Nullspace)

0 comments on commit 3a1d5bc

Please sign in to comment.