{"action":"created","comment":{"url":"https://api.github.com/repos/dealii/dealii/pulls/comments/46834283","id":46834283,"diff_hunk":"@@ -1118,6 +1371,227 @@ linear_operator(const OperatorExemplar &operator_exemplar, const Matrix &matrix)\n \n //@}\n \n+namespace SchurComplement\n+{\n+  /**\n+   * @name Schur Complement operations\n+   */\n+  //@{\n+\n+  /**\n+   * @relates LinearOperator\n+   *\n+   * For the system of equations\n+   * @f{eqnarray*}\n+       (1) \\quad Ax + By &=& f \\\\\n+       (2) \\quad Cx + Dy &=& g \\quad ,\n+   * @f}\n+   * this function performs the pre-processing (condensation)\n+   * step on the RHS subvector @p g so that the Schur complement\n+   * can be used to solve this system of equations.\n+   * More specifically, the forward operation modifies the\n+   * subvector @p g such that\n+   * @f[\n+       g \\quad \\rightarrow \\quad g - C \\: A^{-1} \\: f\n+     @f]\n+   * The reverse operation, only used in the post-processing\n+   * step, reverses this step by modifying the subvector @p g\n+   * such that\n+   * @f[\n+       g \\quad \\rightarrow \\quad g + C \\: A^{-1} \\: f\n+     @f]\n+   *\n+   * @see\n+   * @ref GlossBlockLA \"Block (linear algebra)\"\n+   * @author Jean-Paul Pelteret, 2015\n+   *\n+   * @ingroup LAOperators\n+   */\n+  template <typename Range_1, typename Domain_1,\n+            typename Range_2>\n+  void\n+  preprocess (const LinearOperator<Range_1, Domain_1> &A_inv,\n+              const LinearOperator<Range_2, Domain_1> &C,\n+              const Range_1                           &f,\n+              Range_2                                 &g,\n+              const bool                               forward_op = true)\n+  {\n+    static GrowingVectorMemory<Range_1> vector_memory_f;\n+    static GrowingVectorMemory<Range_2> vector_memory_g;\n+\n+    Range_1 &tmp_f1 = *(vector_memory_f.alloc());\n+    Range_2 &tmp_g1 = *(vector_memory_g.alloc());\n+\n+    // Reinitialise in context of how they'll be used\n+    A_inv.reinit_range_vector(tmp_f1, /*bool omit_zeroing_entries =*/ true);\n+    C.reinit_range_vector(tmp_g1, /*bool omit_zeroing_entries =*/ true);\n+\n+    // Condensation on RHS of one field\n+    // Need to form g* such that g* = g - C*A_inv*f\n+    try\n+      {\n+        A_inv.vmult(tmp_f1, f); // tmp1 = A_inv * f\n+      }\n+    catch (...)\n+      {\n+        AssertThrow(false,\n+                    ExcMessage(\"No convergence in A_inv vmult operation\"));\n+      }\n+    C.vmult(tmp_g1, tmp_f1); // tmp2 = C * A_inv * f\n+\n+    if (forward_op == true)\n+      g -= tmp_g1; // g = g - C * A_inv * f\n+    else\n+      g += tmp_g1; // g = g + C * A_inv * f\n+  }\n+\n+  /**\n+   * @relates LinearOperator\n+   *\n+   * For the system of equations\n+   * @f{eqnarray*}\n+       (1) \\quad Ax + By &=& f \\\\\n+       (2) \\quad Cx + Dy &=& g \\quad ,\n+   * @f}\n+   * this function performs the post-processing step of the\n+   * Schur operation to solve for the second subvector @p x once\n+   * subvector @p y is known:\n+   * @f[\n+       x =  A^{-1}(f - By)\n+     @f]\n+   *\n+   * At the same time we can choose to revert the condensation\n+   * operation performed on the RHS subvector @p g by executing\n+   * the preprocessing step in reverse mode.\n+   * @f[\n+       g \\quad \\rightarrow \\quad g + C \\: A^{-1} \\: f\n+     @f]\n+   *\n+   * @see\n+   * @ref GlossBlockLA \"Block (linear algebra)\"\n+   * @author Jean-Paul Pelteret, 2015\n+   *\n+   * @ingroup LAOperators\n+   */\n+  template <typename Range_1, typename Domain_1,\n+            typename Range_2, typename Domain_2>\n+  void\n+  postprocess (const LinearOperator<Range_1, Domain_1> &A_inv,\n+               const LinearOperator<Range_1, Domain_2> &B,\n+               const LinearOperator<Range_2, Domain_1> &C,\n+               Range_1                                 &x,\n+               const Range_2                           &y,\n+               const Range_1                           &f,\n+               Range_2                                 &g,\n+               const bool                               reverse_condensation = true)\n+  {\n+    static GrowingVectorMemory<Range_1> vector_memory_f;\n+\n+    Range_1 &tmp_f1 = *(vector_memory_f.alloc());\n+    Range_1 &tmp_f2 = *(vector_memory_f.alloc());\n+\n+    // Reinitialise in context of how they'll be used\n+    B.reinit_range_vector(tmp_f1, /*bool omit_zeroing_entries =*/ true);\n+    C.reinit_range_vector(tmp_f2, /*bool omit_zeroing_entries =*/ true);\n+\n+    // Solve for second field\n+    // Need to form x such that x = A_inv*(f - B*y)\n+    B.vmult(tmp_f1, y); // tmp1 = B*y\n+    tmp_f2 = f;\n+    tmp_f2 -= tmp_f1; // tmp2 = f - B*y\n+    try\n+      {\n+        A_inv.vmult(x, tmp_f2); // x = A_inv*(f-B*y)\n+      }\n+    catch (...)\n+      {\n+        AssertThrow(false,\n+                    ExcMessage(\"No convergence in A_inv vmult operation\"));\n+      }\n+\n+    // Need to reverse g*-->g performed in preprocessing\n+    // step so that accurate residual quantification and\n+    // other local static condensation operations, based\n+    // on g, can be computed after solution process.\n+    // i.e. Need to return to g = g* + C*A_inv*f\n+    if (reverse_condensation == true)\n+      preprocess(A_inv,C,\n+                 f,g,\n+                 /*forward_op =*/ false);\n+  }\n+\n+  /**\n+   * @relates LinearOperator\n+   *\n+   * Solve the general system of equations\n+   * @f{eqnarray*}\n+    \\mathbf{K}\\mathbf{d} = \\mathbf{h}\n+    \\quad \\Rightarrow\\quad\n+    \\left(\\begin{array}{cc}\n+      A & B \\\\ C & D\n+    \\end{array}\\right)\n+    \\left(\\begin{array}{cc}\n+      x \\\\ y\n+    \\end{array}\\right)\n+    =\n+    \\left(\\begin{array}{cc}\n+      f \\\\ g\n+    \\end{array}\\right),\n+   * @f}\n+   * using the Schur complement.\n+   *\n+   * @note This requires the pre-construction of @p A_inv,\n+   * the inverse operation of the (square) matrix @p A.\n+   * The @p solver and @p preconditioner are used to construct\n+   * the operation representing the inverse of the Schur\n+   * complement, and should thus be chosen accordingly.\n+   *\n+   * @note The preconditioner could also be an approximation to the\n+   * inverse of Schur complement that is constructed, naturally, using\n+   * the function schur_complement().\n+   *\n+   * @see\n+   * @ref GlossBlockLA \"Block (linear algebra)\"\n+   * @author Jean-Paul Pelteret, 2015\n+   *\n+   * @ingroup LAOperators\n+   */\n+  template <typename Range_1, typename Domain_1,\n+            typename Range_2, typename Domain_2,\n+            typename Solver, typename Preconditioner>\n+  void\n+  solve_system (const LinearOperator<Range_1, Domain_1> &A_inv,\n+                const LinearOperator<Range_1, Domain_2> &B,\n+                const LinearOperator<Range_2, Domain_1> &C,\n+                const LinearOperator<Range_2, Domain_2> &D,\n+                Range_1                                 &x,\n+                Range_2                                 &y,\n+                const Range_1                           &f,\n+                const Range_2                           &g,\n+                Solver                                  &solver,\n+                const Preconditioner                    &preconditioner)","path":"include/deal.II/lac/linear_operator.h","position":486,"original_position":462,"commit_id":"ca2d1a8bcb16915c3d1d1ade99095cf320955086","original_commit_id":"5768da732e7dfacd8890714eec8161986ebdcafd","user":{"login":"jppelteret","id":10460610,"avatar_url":"https://avatars.githubusercontent.com/u/10460610?v=3","gravatar_id":"","url":"https://api.github.com/users/jppelteret","html_url":"https://github.com/jppelteret","followers_url":"https://api.github.com/users/jppelteret/followers","following_url":"https://api.github.com/users/jppelteret/following{/other_user}","gists_url":"https://api.github.com/users/jppelteret/gists{/gist_id}","starred_url":"https://api.github.com/users/jppelteret/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jppelteret/subscriptions","organizations_url":"https://api.github.com/users/jppelteret/orgs","repos_url":"https://api.github.com/users/jppelteret/repos","events_url":"https://api.github.com/users/jppelteret/events{/privacy}","received_events_url":"https://api.github.com/users/jppelteret/received_events","type":"User","site_admin":false},"body":"Awesome. This will be great :-)","created_at":"2015-12-07T15:39:10Z","updated_at":"2015-12-07T15:39:10Z","html_url":"https://github.com/dealii/dealii/pull/1956#discussion_r46834283","pull_request_url":"https://api.github.com/repos/dealii/dealii/pulls/1956","_links":{"self":{"href":"https://api.github.com/repos/dealii/dealii/pulls/comments/46834283"},"html":{"href":"https://github.com/dealii/dealii/pull/1956#discussion_r46834283"},"pull_request":{"href":"https://api.github.com/repos/dealii/dealii/pulls/1956"}}},"pull_request":{"url":"https://api.github.com/repos/dealii/dealii/pulls/1956","id":52846140,"html_url":"https://github.com/dealii/dealii/pull/1956","diff_url":"https://github.com/dealii/dealii/pull/1956.diff","patch_url":"https://github.com/dealii/dealii/pull/1956.patch","issue_url":"https://api.github.com/repos/dealii/dealii/issues/1956","number":1956,"state":"open","locked":false,"title":"[WIP] Schur operator","user":{"login":"jppelteret","id":10460610,"avatar_url":"https://avatars.githubusercontent.com/u/10460610?v=3","gravatar_id":"","url":"https://api.github.com/users/jppelteret","html_url":"https://github.com/jppelteret","followers_url":"https://api.github.com/users/jppelteret/followers","following_url":"https://api.github.com/users/jppelteret/following{/other_user}","gists_url":"https://api.github.com/users/jppelteret/gists{/gist_id}","starred_url":"https://api.github.com/users/jppelteret/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jppelteret/subscriptions","organizations_url":"https://api.github.com/users/jppelteret/orgs","repos_url":"https://api.github.com/users/jppelteret/repos","events_url":"https://api.github.com/users/jppelteret/events{/privacy}","received_events_url":"https://api.github.com/users/jppelteret/received_events","type":"User","site_admin":false},"body":"Implementation of a Schur operator and auxillary functions. Addresses #1439 .\r\n","created_at":"2015-12-07T13:47:06Z","updated_at":"2015-12-07T15:39:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c4e23ad2c063892b6aaa9a4e0468fdb0075544e7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dealii/dealii/pulls/1956/commits","review_comments_url":"https://api.github.com/repos/dealii/dealii/pulls/1956/comments","review_comment_url":"https://api.github.com/repos/dealii/dealii/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dealii/dealii/issues/1956/comments","statuses_url":"https://api.github.com/repos/dealii/dealii/statuses/ca2d1a8bcb16915c3d1d1ade99095cf320955086","head":{"label":"jppelteret:schur_operator","ref":"schur_operator","sha":"ca2d1a8bcb16915c3d1d1ade99095cf320955086","user":{"login":"jppelteret","id":10460610,"avatar_url":"https://avatars.githubusercontent.com/u/10460610?v=3","gravatar_id":"","url":"https://api.github.com/users/jppelteret","html_url":"https://github.com/jppelteret","followers_url":"https://api.github.com/users/jppelteret/followers","following_url":"https://api.github.com/users/jppelteret/following{/other_user}","gists_url":"https://api.github.com/users/jppelteret/gists{/gist_id}","starred_url":"https://api.github.com/users/jppelteret/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jppelteret/subscriptions","organizations_url":"https://api.github.com/users/jppelteret/orgs","repos_url":"https://api.github.com/users/jppelteret/repos","events_url":"https://api.github.com/users/jppelteret/events{/privacy}","received_events_url":"https://api.github.com/users/jppelteret/received_events","type":"User","site_admin":false},"repo":{"id":40106037,"name":"dealii","full_name":"jppelteret/dealii","owner":{"login":"jppelteret","id":10460610,"avatar_url":"https://avatars.githubusercontent.com/u/10460610?v=3","gravatar_id":"","url":"https://api.github.com/users/jppelteret","html_url":"https://github.com/jppelteret","followers_url":"https://api.github.com/users/jppelteret/followers","following_url":"https://api.github.com/users/jppelteret/following{/other_user}","gists_url":"https://api.github.com/users/jppelteret/gists{/gist_id}","starred_url":"https://api.github.com/users/jppelteret/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jppelteret/subscriptions","organizations_url":"https://api.github.com/users/jppelteret/orgs","repos_url":"https://api.github.com/users/jppelteret/repos","events_url":"https://api.github.com/users/jppelteret/events{/privacy}","received_events_url":"https://api.github.com/users/jppelteret/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jppelteret/dealii","description":"The development repository for the deal.II finite element library.","fork":true,"url":"https://api.github.com/repos/jppelteret/dealii","forks_url":"https://api.github.com/repos/jppelteret/dealii/forks","keys_url":"https://api.github.com/repos/jppelteret/dealii/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jppelteret/dealii/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jppelteret/dealii/teams","hooks_url":"https://api.github.com/repos/jppelteret/dealii/hooks","issue_events_url":"https://api.github.com/repos/jppelteret/dealii/issues/events{/number}","events_url":"https://api.github.com/repos/jppelteret/dealii/events","assignees_url":"https://api.github.com/repos/jppelteret/dealii/assignees{/user}","branches_url":"https://api.github.com/repos/jppelteret/dealii/branches{/branch}","tags_url":"https://api.github.com/repos/jppelteret/dealii/tags","blobs_url":"https://api.github.com/repos/jppelteret/dealii/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jppelteret/dealii/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jppelteret/dealii/git/refs{/sha}","trees_url":"https://api.github.com/repos/jppelteret/dealii/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jppelteret/dealii/statuses/{sha}","languages_url":"https://api.github.com/repos/jppelteret/dealii/languages","stargazers_url":"https://api.github.com/repos/jppelteret/dealii/stargazers","contributors_url":"https://api.github.com/repos/jppelteret/dealii/contributors","subscribers_url":"https://api.github.com/repos/jppelteret/dealii/subscribers","subscription_url":"https://api.github.com/repos/jppelteret/dealii/subscription","commits_url":"https://api.github.com/repos/jppelteret/dealii/commits{/sha}","git_commits_url":"https://api.github.com/repos/jppelteret/dealii/git/commits{/sha}","comments_url":"https://api.github.com/repos/jppelteret/dealii/comments{/number}","issue_comment_url":"https://api.github.com/repos/jppelteret/dealii/issues/comments{/number}","contents_url":"https://api.github.com/repos/jppelteret/dealii/contents/{+path}","compare_url":"https://api.github.com/repos/jppelteret/dealii/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jppelteret/dealii/merges","archive_url":"https://api.github.com/repos/jppelteret/dealii/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jppelteret/dealii/downloads","issues_url":"https://api.github.com/repos/jppelteret/dealii/issues{/number}","pulls_url":"https://api.github.com/repos/jppelteret/dealii/pulls{/number}","milestones_url":"https://api.github.com/repos/jppelteret/dealii/milestones{/number}","notifications_url":"https://api.github.com/repos/jppelteret/dealii/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jppelteret/dealii/labels{/name}","releases_url":"https://api.github.com/repos/jppelteret/dealii/releases{/id}","created_at":"2015-08-03T05:08:52Z","updated_at":"2015-08-03T05:09:58Z","pushed_at":"2015-12-07T15:36:29Z","git_url":"git://github.com/jppelteret/dealii.git","ssh_url":"git@github.com:jppelteret/dealii.git","clone_url":"https://github.com/jppelteret/dealii.git","svn_url":"https://github.com/jppelteret/dealii","homepage":"http://www.dealii.org/","size":128539,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dealii:master","ref":"master","sha":"69fe72487bf9b61be21f92e304413e79ed1d0b88","user":{"login":"dealii","id":7506070,"avatar_url":"https://avatars.githubusercontent.com/u/7506070?v=3","gravatar_id":"","url":"https://api.github.com/users/dealii","html_url":"https://github.com/dealii","followers_url":"https://api.github.com/users/dealii/followers","following_url":"https://api.github.com/users/dealii/following{/other_user}","gists_url":"https://api.github.com/users/dealii/gists{/gist_id}","starred_url":"https://api.github.com/users/dealii/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dealii/subscriptions","organizations_url":"https://api.github.com/users/dealii/orgs","repos_url":"https://api.github.com/users/dealii/repos","events_url":"https://api.github.com/users/dealii/events{/privacy}","received_events_url":"https://api.github.com/users/dealii/received_events","type":"Organization","site_admin":false},"repo":{"id":21943980,"name":"dealii","full_name":"dealii/dealii","owner":{"login":"dealii","id":7506070,"avatar_url":"https://avatars.githubusercontent.com/u/7506070?v=3","gravatar_id":"","url":"https://api.github.com/users/dealii","html_url":"https://github.com/dealii","followers_url":"https://api.github.com/users/dealii/followers","following_url":"https://api.github.com/users/dealii/following{/other_user}","gists_url":"https://api.github.com/users/dealii/gists{/gist_id}","starred_url":"https://api.github.com/users/dealii/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dealii/subscriptions","organizations_url":"https://api.github.com/users/dealii/orgs","repos_url":"https://api.github.com/users/dealii/repos","events_url":"https://api.github.com/users/dealii/events{/privacy}","received_events_url":"https://api.github.com/users/dealii/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dealii/dealii","description":"The development repository for the deal.II finite element library.","fork":false,"url":"https://api.github.com/repos/dealii/dealii","forks_url":"https://api.github.com/repos/dealii/dealii/forks","keys_url":"https://api.github.com/repos/dealii/dealii/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dealii/dealii/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dealii/dealii/teams","hooks_url":"https://api.github.com/repos/dealii/dealii/hooks","issue_events_url":"https://api.github.com/repos/dealii/dealii/issues/events{/number}","events_url":"https://api.github.com/repos/dealii/dealii/events","assignees_url":"https://api.github.com/repos/dealii/dealii/assignees{/user}","branches_url":"https://api.github.com/repos/dealii/dealii/branches{/branch}","tags_url":"https://api.github.com/repos/dealii/dealii/tags","blobs_url":"https://api.github.com/repos/dealii/dealii/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dealii/dealii/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dealii/dealii/git/refs{/sha}","trees_url":"https://api.github.com/repos/dealii/dealii/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dealii/dealii/statuses/{sha}","languages_url":"https://api.github.com/repos/dealii/dealii/languages","stargazers_url":"https://api.github.com/repos/dealii/dealii/stargazers","contributors_url":"https://api.github.com/repos/dealii/dealii/contributors","subscribers_url":"https://api.github.com/repos/dealii/dealii/subscribers","subscription_url":"https://api.github.com/repos/dealii/dealii/subscription","commits_url":"https://api.github.com/repos/dealii/dealii/commits{/sha}","git_commits_url":"https://api.github.com/repos/dealii/dealii/git/commits{/sha}","comments_url":"https://api.github.com/repos/dealii/dealii/comments{/number}","issue_comment_url":"https://api.github.com/repos/dealii/dealii/issues/comments{/number}","contents_url":"https://api.github.com/repos/dealii/dealii/contents/{+path}","compare_url":"https://api.github.com/repos/dealii/dealii/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dealii/dealii/merges","archive_url":"https://api.github.com/repos/dealii/dealii/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dealii/dealii/downloads","issues_url":"https://api.github.com/repos/dealii/dealii/issues{/number}","pulls_url":"https://api.github.com/repos/dealii/dealii/pulls{/number}","milestones_url":"https://api.github.com/repos/dealii/dealii/milestones{/number}","notifications_url":"https://api.github.com/repos/dealii/dealii/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dealii/dealii/labels{/name}","releases_url":"https://api.github.com/repos/dealii/dealii/releases{/id}","created_at":"2014-07-17T14:00:26Z","updated_at":"2015-12-05T15:47:21Z","pushed_at":"2015-12-07T15:36:29Z","git_url":"git://github.com/dealii/dealii.git","ssh_url":"git@github.com:dealii/dealii.git","clone_url":"https://github.com/dealii/dealii.git","svn_url":"https://github.com/dealii/dealii","homepage":"http://www.dealii.org/","size":136698,"stargazers_count":110,"watchers_count":110,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":133,"mirror_url":null,"open_issues_count":146,"forks":133,"open_issues":146,"watchers":110,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dealii/dealii/pulls/1956"},"html":{"href":"https://github.com/dealii/dealii/pull/1956"},"issue":{"href":"https://api.github.com/repos/dealii/dealii/issues/1956"},"comments":{"href":"https://api.github.com/repos/dealii/dealii/issues/1956/comments"},"review_comments":{"href":"https://api.github.com/repos/dealii/dealii/pulls/1956/comments"},"review_comment":{"href":"https://api.github.com/repos/dealii/dealii/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dealii/dealii/pulls/1956/commits"},"statuses":{"href":"https://api.github.com/repos/dealii/dealii/statuses/ca2d1a8bcb16915c3d1d1ade99095cf320955086"}}}}