{"action":"created","comment":{"url":"https://api.github.com/repos/geodynamics/aspect/pulls/comments/28977229","id":28977229,"diff_hunk":"@@ -81,196 +91,296 @@ namespace aspect\n     class Translation : public TensorFunction<1,dim>\n     {\n       private:\n-        const unsigned int direction;\n+        const Tensor<1,dim> translation;\n \n       public:\n+        //Constructor for TensorFunction that takes a Cartesian direction (1,2, or 3)\n+        //and creates a translation along that axis \n         Translation(const unsigned int d)\n           :\n-          direction(d)\n+          translation( Point<dim>::unit_vector(d) )\n+        {}\n+\n+        //Constructor for TensorFunction that takes a vector\n+        //and creates a translation along that vector \n+        Translation(const Tensor<1,dim> &t)\n+          :\n+          translation(t)\n         {}\n \n         virtual Tensor<1,dim> value(const Point<dim> &) const\n         {\n-          return Point<dim>::unit_vector(direction);\n+          return translation;\n         }\n     };\n \n   }\n \n   template <int dim>\n-  void Simulator<dim>::setup_nullspace_removal()\n+  void Simulator<dim>::remove_nullspace(LinearAlgebra::BlockVector &relevant_dst,\n+                                        LinearAlgebra::BlockVector &tmp_distributed_stokes)\n   {\n+    if (parameters.nullspace_removal & NullspaceRemoval::angular_momentum)\n+      {\n+        //use_constant_velocity = false, remove net angular momentum\n+        remove_net_angular_momentum( false, relevant_dst, tmp_distributed_stokes);\n+      }\n     if (parameters.nullspace_removal & NullspaceRemoval::linear_momentum)\n-      AssertThrow(false, ExcNotImplemented());\n-\n-    std::vector<std_cxx1x::shared_ptr<TensorFunction<1,dim> > > funcs;\n-\n+      {\n+        //use_constant_velocity = false, remove net momentum\n+        remove_net_linear_momentum( false, relevant_dst, tmp_distributed_stokes);\n+      }\n     if (parameters.nullspace_removal & NullspaceRemoval::net_rotation)\n       {\n-        if (dim==2)\n-          funcs.push_back(std_cxx1x::shared_ptr<TensorFunction<1,dim> >(new internal::Rotation<dim>(0)));\n-        if (dim==3)\n-          for (unsigned int a=0; a<dim; ++a)\n-            funcs.push_back(std_cxx1x::shared_ptr<TensorFunction<1,dim> >(new internal::Rotation<dim>(a)));\n+        //use_constant_velocity = true, remove net rotation\n+        remove_net_angular_momentum( true, relevant_dst, tmp_distributed_stokes);\n       }\n+    if (parameters.nullspace_removal & NullspaceRemoval::net_translation)\n+      {\n+        //use_constant_velocity = true, remove net translation\n+        remove_net_linear_momentum( true, relevant_dst, tmp_distributed_stokes);\n+      }\n+  }\n \n-    if (parameters.nullspace_removal & NullspaceRemoval::net_translation_x)\n-      funcs.push_back(std_cxx1x::shared_ptr<TensorFunction<1,dim> >(new internal::Translation<dim>(0)));\n+  template <int dim>\n+  void Simulator<dim>::remove_net_linear_momentum( const bool use_constant_density,\n+                                                   LinearAlgebra::BlockVector &relevant_dst,\n+                                                   LinearAlgebra::BlockVector &tmp_distributed_stokes )\n+  {\n+    Assert(introspection.block_indices.velocities != introspection.block_indices.pressure,\n+           ExcNotImplemented());\n \n-    if (parameters.nullspace_removal & NullspaceRemoval::net_translation_y)\n-      funcs.push_back(std_cxx1x::shared_ptr<TensorFunction<1,dim> >(new internal::Translation<dim>(1)));\n+    // compute and remove net linear momentum from velocity field, by computing\n+    // \\int \\rho (v + v_const) = 0\n \n-    if (parameters.nullspace_removal & NullspaceRemoval::net_translation_z)\n-      {\n-        //Only do z direction if dim == 3\n-        AssertThrow( dim == 3, ExcMessage(\"Can't remove z translational mode in 2 dimensions\"));\n-        funcs.push_back(std_cxx1x::shared_ptr<TensorFunction<1,dim> >(new internal::Translation<dim>(2)));\n-      }\n+    QGauss<dim> quadrature(parameters.stokes_velocity_degree+1);\n+    FEValues<dim> fe(mapping, finite_element, quadrature,\n+                     UpdateFlags(update_quadrature_points | update_JxW_values | update_values));\n \n-    if (funcs.size()>0)\n-      {\n-        Assert(introspection.block_indices.velocities != introspection.block_indices.pressure,\n-               ExcNotImplemented());\n-\n-        net_rotations_translations.resize(funcs.size());\n-        for (unsigned int i=0; i<funcs.size(); ++i)\n-          {\n-            // for each of the null space dimensions, set up\n-            // a vector, fill it with an element of the null space,\n-            // and normalize it\n-            net_rotations_translations[i].reinit(\n-              introspection.index_sets.system_partitioning[introspection.block_indices.velocities],\n-              mpi_communicator);\n-            interpolate_onto_velocity_system(*funcs[i],\n-                                             net_rotations_translations[i]);\n-            net_rotations_translations[i] /= net_rotations_translations[i].l2_norm();\n-          }\n+    Tensor<1,dim> local_momentum;\n+    double local_mass = 0.0;\n \n-      }\n-  }\n+    typename DoFHandler<dim>::active_cell_iterator cell;\n+    //loop over all local cells\n+    for (cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell)\n+      if (cell->is_locally_owned())\n+        {\n+          fe.reinit (cell);\n+          const std::vector<Point<dim> > &q_points = fe.get_quadrature_points();\n+\n+          //Get the velocity at each quadrature point\n+          std::vector< Tensor<1,dim> > velocities( q_points.size() );\n+          fe[introspection.extractors.velocities].get_function_values (relevant_dst, velocities);\n \n+          // get the density at each quadrature point if necessary\n+          typename MaterialModel::Interface<dim>::MaterialModelInputs in(q_points.size(),\n+                                                                parameters.n_compositional_fields);\n+          typename MaterialModel::Interface<dim>::MaterialModelOutputs out(q_points.size(),\n+                                                                  parameters.n_compositional_fields);\n+          if ( ! use_constant_density)\n+            {\n+              std::vector<std::vector<double> > composition_values (parameters.n_compositional_fields,\n+                                                                    std::vector<double> (q_points.size()));\n \n+              fe[introspection.extractors.pressure].get_function_values (relevant_dst, in.pressure);\n+              fe[introspection.extractors.temperature].get_function_values (relevant_dst, in.temperature);\n+              for (unsigned int c=0; c<parameters.n_compositional_fields; ++c)\n+                fe[introspection.extractors.compositional_fields[c]].get_function_values(relevant_dst,\n+                                                                                composition_values[c]);\n+\n+              for (unsigned int i=0; i<q_points.size(); ++i)\n+                {\n+                  in.position[i] = fe.quadrature_point(i);\n+                  for (unsigned int c=0; c<parameters.n_compositional_fields; ++c)\n+                    in.composition[i][c] = composition_values[c][i];\n+                }\n+              material_model->evaluate(in, out);\n+            }\n \n-  template <int dim>\n-  void Simulator<dim>::remove_nullspace(LinearAlgebra::BlockVector &relevant_dst,\n-                                        LinearAlgebra::BlockVector &tmp_distributed_stokes)\n-  {\n-    if (parameters.nullspace_removal & NullspaceRemoval::net_rotation ||\n-        parameters.nullspace_removal & NullspaceRemoval::net_translation )\n+          // actually compute the momentum and mass\n+          for (unsigned int k=0; k< quadrature.size(); ++k)\n+            {\n+              // get the density at this quadrature point\n+              double rho = (use_constant_density ? 1.0 : out.densities[k]);\n+\n+              local_momentum += velocities[k] * rho * fe.JxW(k);\n+              local_mass += rho + fe.JxW(k); \n+            }\n+        }\n+\n+    //Calculate the total mass and velocity correction\n+    const double mass = dealii::Utilities::MPI::sum( local_mass, mpi_communicator);\n+    Tensor<1,dim> velocity_correction = dealii::Utilities::MPI::reduce_tensor(local_momentum, mpi_communicator)/mass;\n+\n+    //We may only want to remove the nullspace for a single component, so zero out\n+    //the velocity correction if it is not selected by the NullspaceRemoval flag\n+    if (use_constant_density) //disable translation correction\n       {\n-        Assert(introspection.block_indices.velocities != introspection.block_indices.pressure,\n-               ExcNotImplemented());\n-\n-        for (unsigned int i=0; i<net_rotations_translations.size(); ++i)\n-          {\n-            // compute the magnitude of the solution vector in direction\n-            // of this null space vector and subtract the corresponding multiple\n-            const double power = net_rotations_translations[i]\n-                                 * tmp_distributed_stokes.block(introspection.block_indices.velocities);\n-            tmp_distributed_stokes.block(introspection.block_indices.velocities).sadd(1.0,\n-                                                                                      -1.0*power,\n-                                                                                      net_rotations_translations[i]);\n-          }\n-        relevant_dst.block(0) = tmp_distributed_stokes.block(0);\n+        if( !(parameters.nullspace_removal & NullspaceRemoval::net_translation_x) )\n+          velocity_correction[0] = 0.0;  //don't correct x translation\n+        if( !(parameters.nullspace_removal & NullspaceRemoval::net_translation_y) )\n+          velocity_correction[1] = 0.0;  //don't correct y translation\n+        if( !(parameters.nullspace_removal & NullspaceRemoval::net_translation_z) && dim == 3 )\n+          velocity_correction[2] = 0.0;  //don't correct z translation\n       }\n-    if (parameters.nullspace_removal & NullspaceRemoval::angular_momentum)\n+    else //disable momentum correction\n       {\n-        remove_net_angular_momentum( relevant_dst, tmp_distributed_stokes);\n+        if( !(parameters.nullspace_removal & NullspaceRemoval::linear_momentum_x) )\n+          velocity_correction[0] = 0.0;  //don't correct x translation\n+        if( !(parameters.nullspace_removal & NullspaceRemoval::linear_momentum_y) )\n+          velocity_correction[1] = 0.0;  //don't correct y translation\n+        if( !(parameters.nullspace_removal & NullspaceRemoval::linear_momentum_z) && dim == 3 )\n+          velocity_correction[2] = 0.0;  //don't correct z translation\n       }\n-  }\n \n+    //vector for storing the correction to the velocity field\n+    LinearAlgebra::Vector correction(tmp_distributed_stokes.block(introspection.block_indices.velocities));\n \n+    // Now construct a translation vector with the desired rate and subtract it from our vector\n+    internal::Translation<dim> translation( velocity_correction );\n+    interpolate_onto_velocity_system(translation, correction);\n+    tmp_distributed_stokes.block(introspection.block_indices.velocities).add(-1.0,correction);\n \n-  template <>\n-  void\n-  Simulator<3>::remove_net_angular_momentum( LinearAlgebra::BlockVector &relevant_dst,\n-                                             LinearAlgebra::BlockVector &tmp_distributed_stokes )\n-  {\n-    AssertThrow(false, ExcNotImplemented());\n+    //copy into the locally relevant vector\n+    relevant_dst.block(introspection.block_indices.velocities) = \n+            tmp_distributed_stokes.block(introspection.block_indices.velocities);\n   }\n \n-\n-  template <>\n-  void\n-  Simulator<2>::remove_net_angular_momentum( LinearAlgebra::BlockVector &relevant_dst,\n-                                             LinearAlgebra::BlockVector &tmp_distributed_stokes )\n+  template <int dim>\n+  void Simulator<dim>::remove_net_angular_momentum( const bool use_constant_density, \n+                                                    LinearAlgebra::BlockVector &relevant_dst,\n+                                                    LinearAlgebra::BlockVector &tmp_distributed_stokes)\n   {\n     Assert(introspection.block_indices.velocities != introspection.block_indices.pressure,\n            ExcNotImplemented());\n \n     // compute and remove angular momentum from velocity field, by computing\n-    // int rho V \\cdot r_orth = omega  * int rho x^2\n-    const unsigned int dim=2;\n-\n+    // \\int \\rho u \\cdot r_orth = \\omega  * \\int \\rho x^2    ( 2 dimensions)\n+    // \\int \\rho r \\times u =  I^{-1} \\cdot \\omega  (3 dimensions)\n+    \n     QGauss<dim> quadrature(parameters.stokes_velocity_degree+1);\n     FEValues<dim> fe(mapping, finite_element, quadrature,\n                      UpdateFlags(update_quadrature_points | update_JxW_values | update_values));\n \n-    DoFHandler<dim>::active_cell_iterator cell;\n-    std::vector<Point<dim> > q_points(quadrature.size());\n-    std::vector<Vector<double> > fe_vals(quadrature.size(), Vector<double>(finite_element.n_components()));\n+    typename DoFHandler<dim>::active_cell_iterator cell;\n+\n+    // moment of inertia and angular momentum for 3D\n+    SymmetricTensor<2,dim> local_moment_of_inertia;\n+    Tensor<1,dim> local_angular_momentum;\n \n     // analogues to the moment of inertia and angular momentum for 2D\n-    double local_scalar_moment = 0;\n-    double local_scalar_angular_momentum = 0;\n+    double local_scalar_moment = 0.0;\n+    double local_scalar_angular_momentum = 0.0;\n \n     //loop over all local cells\n     for (cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell)\n       if (cell->is_locally_owned())\n         {\n           fe.reinit (cell);\n-          q_points = fe.get_quadrature_points();\n-          fe.get_function_values(relevant_dst, fe_vals);\n+          const std::vector<Point<dim> > &q_points = fe.get_quadrature_points();\n+\n+          //Get the velocity at each quadrature point\n+          std::vector< Tensor<1,dim> > velocities( q_points.size() );\n+          fe[introspection.extractors.velocities].get_function_values (relevant_dst, velocities);\n \n-          // get the density at each quadrature point\n-          MaterialModel::Interface<dim>::MaterialModelInputs in(q_points.size(),\n+          // get the density at each quadrature point if necessary\n+          typename MaterialModel::Interface<dim>::MaterialModelInputs in(q_points.size(),\n                                                                 parameters.n_compositional_fields);\n-          MaterialModel::Interface<dim>::MaterialModelOutputs out(q_points.size(),\n+          typename MaterialModel::Interface<dim>::MaterialModelOutputs out(q_points.size(),\n                                                                   parameters.n_compositional_fields);\n-          for (unsigned int i=0; i< q_points.size(); i++)\n+          if ( ! use_constant_density)\n             {\n-              in.pressure[i] = fe_vals[i][introspection.component_indices.pressure];\n-              in.temperature[i] = fe_vals[i][introspection.component_indices.temperature];\n-              for (unsigned int c=0; c<parameters.n_compositional_fields; ++c)\n-                in.composition[i][c] = fe_vals[i][introspection.component_indices.compositional_fields[c]];\n-              in.position[i] = q_points[i];\n+              std::vector<std::vector<double> > composition_values (parameters.n_compositional_fields,\n+                                                                    std::vector<double> (q_points.size()));","path":"source/simulator/nullspace.cc","position":333,"original_position":333,"commit_id":"6cdb7209b1b11d3cab9520b3f9e11a0dd51bc2da","original_commit_id":"6cdb7209b1b11d3cab9520b3f9e11a0dd51bc2da","user":{"login":"bangerth","id":7504421,"avatar_url":"https://avatars.githubusercontent.com/u/7504421?v=3","gravatar_id":"","url":"https://api.github.com/users/bangerth","html_url":"https://github.com/bangerth","followers_url":"https://api.github.com/users/bangerth/followers","following_url":"https://api.github.com/users/bangerth/following{/other_user}","gists_url":"https://api.github.com/users/bangerth/gists{/gist_id}","starred_url":"https://api.github.com/users/bangerth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bangerth/subscriptions","organizations_url":"https://api.github.com/users/bangerth/orgs","repos_url":"https://api.github.com/users/bangerth/repos","events_url":"https://api.github.com/users/bangerth/events{/privacy}","received_events_url":"https://api.github.com/users/bangerth/received_events","type":"User","site_admin":false},"body":"same here -- move the declaration out of the loop.","created_at":"2015-04-23T16:08:25Z","updated_at":"2015-04-23T16:08:25Z","html_url":"https://github.com/geodynamics/aspect/pull/305#discussion_r28977229","pull_request_url":"https://api.github.com/repos/geodynamics/aspect/pulls/305","_links":{"self":{"href":"https://api.github.com/repos/geodynamics/aspect/pulls/comments/28977229"},"html":{"href":"https://github.com/geodynamics/aspect/pull/305#discussion_r28977229"},"pull_request":{"href":"https://api.github.com/repos/geodynamics/aspect/pulls/305"}}},"pull_request":{"url":"https://api.github.com/repos/geodynamics/aspect/pulls/305","id":33633100,"html_url":"https://github.com/geodynamics/aspect/pull/305","diff_url":"https://github.com/geodynamics/aspect/pull/305.diff","patch_url":"https://github.com/geodynamics/aspect/pull/305.patch","issue_url":"https://api.github.com/repos/geodynamics/aspect/issues/305","number":305,"state":"open","locked":false,"title":"Fix nullspace removal","user":{"login":"ian-r-rose","id":5728311,"avatar_url":"https://avatars.githubusercontent.com/u/5728311?v=3","gravatar_id":"","url":"https://api.github.com/users/ian-r-rose","html_url":"https://github.com/ian-r-rose","followers_url":"https://api.github.com/users/ian-r-rose/followers","following_url":"https://api.github.com/users/ian-r-rose/following{/other_user}","gists_url":"https://api.github.com/users/ian-r-rose/gists{/gist_id}","starred_url":"https://api.github.com/users/ian-r-rose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ian-r-rose/subscriptions","organizations_url":"https://api.github.com/users/ian-r-rose/orgs","repos_url":"https://api.github.com/users/ian-r-rose/repos","events_url":"https://api.github.com/users/ian-r-rose/events{/privacy}","received_events_url":"https://api.github.com/users/ian-r-rose/received_events","type":"User","site_admin":false},"body":"Addresses #304.\r\n\r\nTaking a crack at patching up the nullspace removal, and I thought I'd ask everyone their opinion here.  First of all, I've added some important and previously-missing routines, (angular momentum in 3D, linear momentum).\r\n\r\nSecond, I've managed to confuse myself a bit.  The new angular momentum removal function seems to fix the solid body rotation problem in #304.  So that is all well and good.  However, I am puzzled about the net rotation removal.  The strategy we have used is\r\n\r\n* construct a solid body rotation (or translation) vector, under the theory that we know it is in the nullspace for specific cases\r\n* project that solid body rotation (or translation) out of the solution vector using solution = solution - (rotation*solution) rotation\r\n\r\nSo my questions are:\r\n(1) Is this obviously flawed?\r\n(2) If so, is it worth trying to fix, or should we just stick to the more physical angular/linear momentum removal routines?\r\n(3) This PR currently does not allow separate removal of x,y,or z translations.  It just removes all momentum.  Are there specific use cases where we need the granularity to specify which direction to remove?\r\n\r\n","created_at":"2015-04-20T03:19:29Z","updated_at":"2015-04-23T16:08:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3585c5256eac643ef55054826c36bd33a9568574","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/geodynamics/aspect/pulls/305/commits","review_comments_url":"https://api.github.com/repos/geodynamics/aspect/pulls/305/comments","review_comment_url":"https://api.github.com/repos/geodynamics/aspect/pulls/comments{/number}","comments_url":"https://api.github.com/repos/geodynamics/aspect/issues/305/comments","statuses_url":"https://api.github.com/repos/geodynamics/aspect/statuses/6cdb7209b1b11d3cab9520b3f9e11a0dd51bc2da","head":{"label":"ian-r-rose:fix_nullspace_removal","ref":"fix_nullspace_removal","sha":"6cdb7209b1b11d3cab9520b3f9e11a0dd51bc2da","user":{"login":"ian-r-rose","id":5728311,"avatar_url":"https://avatars.githubusercontent.com/u/5728311?v=3","gravatar_id":"","url":"https://api.github.com/users/ian-r-rose","html_url":"https://github.com/ian-r-rose","followers_url":"https://api.github.com/users/ian-r-rose/followers","following_url":"https://api.github.com/users/ian-r-rose/following{/other_user}","gists_url":"https://api.github.com/users/ian-r-rose/gists{/gist_id}","starred_url":"https://api.github.com/users/ian-r-rose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ian-r-rose/subscriptions","organizations_url":"https://api.github.com/users/ian-r-rose/orgs","repos_url":"https://api.github.com/users/ian-r-rose/repos","events_url":"https://api.github.com/users/ian-r-rose/events{/privacy}","received_events_url":"https://api.github.com/users/ian-r-rose/received_events","type":"User","site_admin":false},"repo":{"id":19902476,"name":"aspect","full_name":"ian-r-rose/aspect","owner":{"login":"ian-r-rose","id":5728311,"avatar_url":"https://avatars.githubusercontent.com/u/5728311?v=3","gravatar_id":"","url":"https://api.github.com/users/ian-r-rose","html_url":"https://github.com/ian-r-rose","followers_url":"https://api.github.com/users/ian-r-rose/followers","following_url":"https://api.github.com/users/ian-r-rose/following{/other_user}","gists_url":"https://api.github.com/users/ian-r-rose/gists{/gist_id}","starred_url":"https://api.github.com/users/ian-r-rose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ian-r-rose/subscriptions","organizations_url":"https://api.github.com/users/ian-r-rose/orgs","repos_url":"https://api.github.com/users/ian-r-rose/repos","events_url":"https://api.github.com/users/ian-r-rose/events{/privacy}","received_events_url":"https://api.github.com/users/ian-r-rose/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ian-r-rose/aspect","description":"Finite element parallel code to simulate problems in thermal convection in both 2D and 3D models.","fork":true,"url":"https://api.github.com/repos/ian-r-rose/aspect","forks_url":"https://api.github.com/repos/ian-r-rose/aspect/forks","keys_url":"https://api.github.com/repos/ian-r-rose/aspect/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ian-r-rose/aspect/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ian-r-rose/aspect/teams","hooks_url":"https://api.github.com/repos/ian-r-rose/aspect/hooks","issue_events_url":"https://api.github.com/repos/ian-r-rose/aspect/issues/events{/number}","events_url":"https://api.github.com/repos/ian-r-rose/aspect/events","assignees_url":"https://api.github.com/repos/ian-r-rose/aspect/assignees{/user}","branches_url":"https://api.github.com/repos/ian-r-rose/aspect/branches{/branch}","tags_url":"https://api.github.com/repos/ian-r-rose/aspect/tags","blobs_url":"https://api.github.com/repos/ian-r-rose/aspect/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ian-r-rose/aspect/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ian-r-rose/aspect/git/refs{/sha}","trees_url":"https://api.github.com/repos/ian-r-rose/aspect/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ian-r-rose/aspect/statuses/{sha}","languages_url":"https://api.github.com/repos/ian-r-rose/aspect/languages","stargazers_url":"https://api.github.com/repos/ian-r-rose/aspect/stargazers","contributors_url":"https://api.github.com/repos/ian-r-rose/aspect/contributors","subscribers_url":"https://api.github.com/repos/ian-r-rose/aspect/subscribers","subscription_url":"https://api.github.com/repos/ian-r-rose/aspect/subscription","commits_url":"https://api.github.com/repos/ian-r-rose/aspect/commits{/sha}","git_commits_url":"https://api.github.com/repos/ian-r-rose/aspect/git/commits{/sha}","comments_url":"https://api.github.com/repos/ian-r-rose/aspect/comments{/number}","issue_comment_url":"https://api.github.com/repos/ian-r-rose/aspect/issues/comments{/number}","contents_url":"https://api.github.com/repos/ian-r-rose/aspect/contents/{+path}","compare_url":"https://api.github.com/repos/ian-r-rose/aspect/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ian-r-rose/aspect/merges","archive_url":"https://api.github.com/repos/ian-r-rose/aspect/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ian-r-rose/aspect/downloads","issues_url":"https://api.github.com/repos/ian-r-rose/aspect/issues{/number}","pulls_url":"https://api.github.com/repos/ian-r-rose/aspect/pulls{/number}","milestones_url":"https://api.github.com/repos/ian-r-rose/aspect/milestones{/number}","notifications_url":"https://api.github.com/repos/ian-r-rose/aspect/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ian-r-rose/aspect/labels{/name}","releases_url":"https://api.github.com/repos/ian-r-rose/aspect/releases{/id}","created_at":"2014-05-18T04:04:13Z","updated_at":"2015-04-16T17:19:48Z","pushed_at":"2015-04-22T01:02:23Z","git_url":"git://github.com/ian-r-rose/aspect.git","ssh_url":"git@github.com:ian-r-rose/aspect.git","clone_url":"https://github.com/ian-r-rose/aspect.git","svn_url":"https://github.com/ian-r-rose/aspect","homepage":null,"size":98555,"stargazers_count":0,"watchers_count":0,"language":"Gnuplot","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":"geodynamics:master","ref":"master","sha":"1411d5cdc61edffa7cdc84d8c46b14d5ede7e62b","user":{"login":"geodynamics","id":4052461,"avatar_url":"https://avatars.githubusercontent.com/u/4052461?v=3","gravatar_id":"","url":"https://api.github.com/users/geodynamics","html_url":"https://github.com/geodynamics","followers_url":"https://api.github.com/users/geodynamics/followers","following_url":"https://api.github.com/users/geodynamics/following{/other_user}","gists_url":"https://api.github.com/users/geodynamics/gists{/gist_id}","starred_url":"https://api.github.com/users/geodynamics/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/geodynamics/subscriptions","organizations_url":"https://api.github.com/users/geodynamics/orgs","repos_url":"https://api.github.com/users/geodynamics/repos","events_url":"https://api.github.com/users/geodynamics/events{/privacy}","received_events_url":"https://api.github.com/users/geodynamics/received_events","type":"Organization","site_admin":false},"repo":{"id":19502452,"name":"aspect","full_name":"geodynamics/aspect","owner":{"login":"geodynamics","id":4052461,"avatar_url":"https://avatars.githubusercontent.com/u/4052461?v=3","gravatar_id":"","url":"https://api.github.com/users/geodynamics","html_url":"https://github.com/geodynamics","followers_url":"https://api.github.com/users/geodynamics/followers","following_url":"https://api.github.com/users/geodynamics/following{/other_user}","gists_url":"https://api.github.com/users/geodynamics/gists{/gist_id}","starred_url":"https://api.github.com/users/geodynamics/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/geodynamics/subscriptions","organizations_url":"https://api.github.com/users/geodynamics/orgs","repos_url":"https://api.github.com/users/geodynamics/repos","events_url":"https://api.github.com/users/geodynamics/events{/privacy}","received_events_url":"https://api.github.com/users/geodynamics/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/geodynamics/aspect","description":"A parallel, extendible finite element code to simulate thermal convection in both 2D and 3D models.","fork":false,"url":"https://api.github.com/repos/geodynamics/aspect","forks_url":"https://api.github.com/repos/geodynamics/aspect/forks","keys_url":"https://api.github.com/repos/geodynamics/aspect/keys{/key_id}","collaborators_url":"https://api.github.com/repos/geodynamics/aspect/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/geodynamics/aspect/teams","hooks_url":"https://api.github.com/repos/geodynamics/aspect/hooks","issue_events_url":"https://api.github.com/repos/geodynamics/aspect/issues/events{/number}","events_url":"https://api.github.com/repos/geodynamics/aspect/events","assignees_url":"https://api.github.com/repos/geodynamics/aspect/assignees{/user}","branches_url":"https://api.github.com/repos/geodynamics/aspect/branches{/branch}","tags_url":"https://api.github.com/repos/geodynamics/aspect/tags","blobs_url":"https://api.github.com/repos/geodynamics/aspect/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/geodynamics/aspect/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/geodynamics/aspect/git/refs{/sha}","trees_url":"https://api.github.com/repos/geodynamics/aspect/git/trees{/sha}","statuses_url":"https://api.github.com/repos/geodynamics/aspect/statuses/{sha}","languages_url":"https://api.github.com/repos/geodynamics/aspect/languages","stargazers_url":"https://api.github.com/repos/geodynamics/aspect/stargazers","contributors_url":"https://api.github.com/repos/geodynamics/aspect/contributors","subscribers_url":"https://api.github.com/repos/geodynamics/aspect/subscribers","subscription_url":"https://api.github.com/repos/geodynamics/aspect/subscription","commits_url":"https://api.github.com/repos/geodynamics/aspect/commits{/sha}","git_commits_url":"https://api.github.com/repos/geodynamics/aspect/git/commits{/sha}","comments_url":"https://api.github.com/repos/geodynamics/aspect/comments{/number}","issue_comment_url":"https://api.github.com/repos/geodynamics/aspect/issues/comments{/number}","contents_url":"https://api.github.com/repos/geodynamics/aspect/contents/{+path}","compare_url":"https://api.github.com/repos/geodynamics/aspect/compare/{base}...{head}","merges_url":"https://api.github.com/repos/geodynamics/aspect/merges","archive_url":"https://api.github.com/repos/geodynamics/aspect/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/geodynamics/aspect/downloads","issues_url":"https://api.github.com/repos/geodynamics/aspect/issues{/number}","pulls_url":"https://api.github.com/repos/geodynamics/aspect/pulls{/number}","milestones_url":"https://api.github.com/repos/geodynamics/aspect/milestones{/number}","notifications_url":"https://api.github.com/repos/geodynamics/aspect/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/geodynamics/aspect/labels{/name}","releases_url":"https://api.github.com/repos/geodynamics/aspect/releases{/id}","created_at":"2014-05-06T16:47:18Z","updated_at":"2015-04-20T02:24:15Z","pushed_at":"2015-04-23T15:24:46Z","git_url":"git://github.com/geodynamics/aspect.git","ssh_url":"git@github.com:geodynamics/aspect.git","clone_url":"https://github.com/geodynamics/aspect.git","svn_url":"https://github.com/geodynamics/aspect","homepage":"http://aspect.dealii.org/","size":112355,"stargazers_count":10,"watchers_count":10,"language":"Gnuplot","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":26,"mirror_url":null,"open_issues_count":38,"forks":26,"open_issues":38,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/geodynamics/aspect/pulls/305"},"html":{"href":"https://github.com/geodynamics/aspect/pull/305"},"issue":{"href":"https://api.github.com/repos/geodynamics/aspect/issues/305"},"comments":{"href":"https://api.github.com/repos/geodynamics/aspect/issues/305/comments"},"review_comments":{"href":"https://api.github.com/repos/geodynamics/aspect/pulls/305/comments"},"review_comment":{"href":"https://api.github.com/repos/geodynamics/aspect/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/geodynamics/aspect/pulls/305/commits"},"statuses":{"href":"https://api.github.com/repos/geodynamics/aspect/statuses/6cdb7209b1b11d3cab9520b3f9e11a0dd51bc2da"}}}}