aboutsummaryrefslogtreecommitdiff
path: root/src/gr/horizon_Jacobian.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gr/horizon_Jacobian.cc')
-rw-r--r--src/gr/horizon_Jacobian.cc115
1 files changed, 107 insertions, 8 deletions
diff --git a/src/gr/horizon_Jacobian.cc b/src/gr/horizon_Jacobian.cc
index 7718796..bcaec78 100644
--- a/src/gr/horizon_Jacobian.cc
+++ b/src/gr/horizon_Jacobian.cc
@@ -3,9 +3,11 @@
//
// <<<prototypes for functions local to this file>>>
// create_Jacobian - create a Jacobian matrix of the appropriate type
-// horizon_Jacobian - top-level driver to compute the Jacobian
+//
+// horizon_Jacobian_SD - compute the Jacobian by symbolic differentiation
/// add_ghost_zone_Jacobian - add ghost zone dependencies to Jacobian
//
+// horizon_Jacobian_NP - compute the Jacobian by numerical perturbation
#include <stdio.h>
#include <assert.h>
@@ -53,12 +55,18 @@ void add_ghost_zone_Jacobian(const patch_system& ps,
}
//******************************************************************************
+//******************************************************************************
+//******************************************************************************
//
// This function decodes the Jacobian_type parameter and creates the
// appropriate type of Jacobian matrix object.
//
-Jacobian& create_Jacobian(const patch_system& ps,
+// FIXME: the patch system shouldn't really have to be non-const, but
+// the Jacobian constructors all require this to allow the
+// linear solvers to directly update gridfns
+//
+Jacobian& create_Jacobian(patch_system& ps,
const char Jacobian_type[])
{
if (STRING_EQUAL(Jacobian_type, "dense matrix"))
@@ -69,12 +77,14 @@ else CCTK_VWarn(-1, __LINE__, __FILE__, CCTK_THORNSTRING,
}
//******************************************************************************
+//******************************************************************************
+//******************************************************************************
//
// This function computes the Jacobian matrix of the LHS function H(h)
-// from the Jacobian coefficient (angular) gridfns. The computation is
-// done a Jacobian row at a time, using equation (25) of my 1996 apparent
-// horizon finding paper.
+// by symbolic differentiation from the Jacobian coefficient (angular)
+// gridfns. The computation is done a Jacobian row at a time, using
+// equation (25) of my 1996 apparent horizon finding paper.
//
// Inputs (angular gridfns, on ghosted grid):
// h # shape of trial surface
@@ -84,9 +94,10 @@ else CCTK_VWarn(-1, __LINE__, __FILE__, CCTK_THORNSTRING,
// Outputs:
// The Jacobian matrix is stored in the Jacobian object Jac.
//
-void horizon_Jacobian(patch_system& ps, Jacobian& Jac)
+void horizon_Jacobian_SD(patch_system& ps,
+ Jacobian& Jac)
{
-CCTK_VInfo(CCTK_THORNSTRING, " horizon Jacobian");
+CCTK_VInfo(CCTK_THORNSTRING, " horizon Jacobian_SD");
ps.compute_synchronize_Jacobian();
Jac.zero();
@@ -189,7 +200,7 @@ Jac.zero();
if (xp.is_in_nominal_grid(xm_irho, xm_isigma))
then Jac(II, xp,xm_irho,xm_isigma) += Jac_rho_sigma;
else add_ghost_zone_Jacobian
- (ps, xp,
+ (ps, xp,
xp.corner_ghost_zone_containing_point(m_irho < 0, m_isigma < 0,
xm_irho, xm_isigma),
II, xm_irho, xm_isigma,
@@ -254,3 +265,91 @@ const int ym_ipar_posn = ps.synchronize_Jacobian_y_ipar_posn
}
}
}
+
+//******************************************************************************
+//******************************************************************************
+//******************************************************************************
+
+//
+// This function computes the Jacobian matrix of the LHS function H(h)
+// by numerical perturbation of the H(h) function. The algorithm is as
+// follows:
+//
+// evaluate H(h)
+// array-copy H(h) to scratch array save_H
+// for each point (y,JJ)
+// {
+// const fp save_h_y = h at y;
+// h at y += perturbation_amplitude;
+// evaluate H(h)
+// for each point (x,II)
+// {
+// Jac(II,JJ) = (H(II) - save_H(II)) / perturbation_amplitude;
+// }
+// h at y = save_h_y;
+// }
+// array-copy save_H back to H(h)
+//
+void horizon_Jacobian_NP(patch_system& ps,
+ const struct cactus_grid_info& cgi,
+ const struct geometry_interpolator_info& ii,
+ Jacobian& Jac,
+ fp perturbation_amplitude)
+{
+CCTK_VInfo(CCTK_THORNSTRING, " horizon Jacobian_NP");
+
+// evaluate H(h)
+jtutil::norm<fp> H_norms;
+horizon_function(ps, cgi, ii, false, H_norms);
+
+// array-copy H(h) to scratch array save_H
+fp *save_H = new fp[Jac.NN()];
+jtutil::array_copy(Jac.NN(), ps.gridfn_data(nominal_gfns::gfn__H), save_H);
+
+ for (int ypn = 0 ; ypn < ps.N_patches() ; ++ypn)
+ {
+ patch& yp = ps.ith_patch(ypn);
+ CCTK_VInfo(CCTK_THORNSTRING, " perturbing in %s patch", yp.name());
+
+ for (int y_irho = yp.min_irho() ; y_irho <= yp.max_irho() ; ++y_irho)
+ {
+ for (int y_isigma = yp.min_isigma() ;
+ y_isigma <= yp.max_isigma() ;
+ ++y_isigma)
+ {
+ const int JJ = ps.gpn_of_patch_irho_isigma(yp, y_irho,y_isigma);
+
+ const fp save_h_y = yp.ghosted_gridfn(ghosted_gfns::gfn__h,
+ y_irho,y_isigma);
+ yp.ghosted_gridfn(ghosted_gfns::gfn__h, y_irho,y_isigma)
+ += perturbation_amplitude;
+ H_norms.reset();
+ horizon_function(ps, cgi, ii, false, H_norms, false);
+ for (int xpn = 0 ; xpn < ps.N_patches() ; ++xpn)
+ {
+ patch& xp = ps.ith_patch(xpn);
+
+ for (int x_irho = xp.min_irho() ;
+ x_irho <= xp.max_irho() ;
+ ++x_irho)
+ {
+ for (int x_isigma = xp.min_isigma() ;
+ x_isigma <= xp.max_isigma() ;
+ ++x_isigma)
+ {
+ const int II = ps.gpn_of_patch_irho_isigma(xp, x_irho,x_isigma);
+ const fp new_xH = xp.gridfn(nominal_gfns::gfn__H,
+ x_irho,x_isigma);
+ Jac(II,JJ) = (new_xH - save_H[II]) / perturbation_amplitude;
+ }
+ }
+ }
+ yp.ghosted_gridfn(ghosted_gfns::gfn__h, y_irho,y_isigma)
+ = save_h_y;
+ }
+ }
+ }
+
+jtutil::array_copy(Jac.NN(), save_H, ps.gridfn_data(nominal_gfns::gfn__H));
+delete[] save_H;
+}