diff options
Diffstat (limited to 'src/patch')
-rw-r--r-- | src/patch/ghost_zone.hh | 14 | ||||
-rw-r--r-- | src/patch/patch_system.cc | 325 | ||||
-rw-r--r-- | src/patch/patch_system.hh | 54 | ||||
-rw-r--r-- | src/patch/test_coords2.cc | 2 | ||||
-rw-r--r-- | src/patch/test_patch_system.cc | 21 |
5 files changed, 267 insertions, 149 deletions
diff --git a/src/patch/ghost_zone.hh b/src/patch/ghost_zone.hh index 3a8e21d..408c162 100644 --- a/src/patch/ghost_zone.hh +++ b/src/patch/ghost_zone.hh @@ -110,7 +110,7 @@ // given point is a member of both adjacent corners), or split down its // diagonal (so any given point is a member of only one corner). This // 3-phase algorithm is actually implemented by -// patch_system::synchronize_ghost_zones() +// patch_system::synchronize() // which in turn calls // symmetry_ghost_zone::synchronize() // interpatch_ghost_zone::synchronize() @@ -257,7 +257,7 @@ public: // ghost zone's synchronize() operation -- it does *NOT* take // into account the 3-phase synchronization algorithm described // in the header comments for this file. (That's done by - // patch_system::synchronize_ghost_zones_Jacobian() .) + // patch_system::synchronize_Jacobian() and its subfunctions.) // // n.b. terminology is // partial gridfn at x @@ -273,15 +273,15 @@ public: // // The API in the remaining functions implicitly assumes that // the Jacobian is independent of ghosted_gfn , and also that - // the structure of the Jacobian is "simple", in that the set of - // y points (with nonzero Jacobian values) in a single row of the - // Jacobian matrix (i.e. the set of points on which a single - // ghost-zone point depends), + // the structure of the Jacobian is such that the set of y points + // (with nonzero Jacobian values) in a single row of the Jacobian + // matrix (i.e. the set of points on which a single ghost-zone point + // depends), // - lies entirely within a single y patch // - has the same number of points for every x point in this ghost zone // - has a single yiperp value (depending on our iperp, of course) // - have a contiguous interval of yipar (depending on our iperp - //and ipar, of course), whose size is + // and ipar, of course), whose size is // [or can be taken to be without an unreasonable // amount of zero-padding] // independent of our iperp and ipar; we parameterize this diff --git a/src/patch/patch_system.cc b/src/patch/patch_system.cc index a11a9d3..b775b3c 100644 --- a/src/patch/patch_system.cc +++ b/src/patch/patch_system.cc @@ -22,7 +22,10 @@ // patch_system::type_of_name // patch_system::patch_number_of_name // -// patch_system::synchronize_ghost_zones +// patch_system::synchronize +// patch_system::compute_synchronize_Jacobian +// patch_system::synchronize_Jacobian_y_ipar_posn +// patch_system::synchronize_Jacobian // // patch_system::print_unknown_gridfn // patch_system::read_unknown_gridfn @@ -870,8 +873,8 @@ void patch_system::assert_all_ghost_zones_fully_setup() const // // Results: // This function returns a reference to the decoded patch. (An alternative -// design would be to return this via a patch*& argument, but design here -// avoids fiddling with pointers.) +// design would be to return this via a patch*& argument, but the design +// used here seems slightly cleaner to use in practice.) // patch& patch_system::patch_irho_isigma_of_gpn(int gpn, int& irho, int& isigma) const @@ -914,8 +917,8 @@ error_exit(PANIC_EXIT, // // Results: // This function returns a reference to the decoded patch. (An alternative -// design would be to return this via a patch*& argument, but design here -// avoids fiddling with pointers.) +// design would be to return this via a patch*& argument, but the design +// used here seems slightly cleaner to use in practice.) // patch& patch_system::ghosted_patch_irho_isigma_of_gpn (int gpn, int& irho, int& isigma) @@ -1054,14 +1057,13 @@ error_exit(ERROR_EXIT, //****************************************************************************** // -// This function "synchronizes" all ghost zones of all patches, i.e. -// it update the ghost-zone values of the specified gridfns via the -// appropriate sequence of symmetry operations and interpatch interpolations. -// This process is described in detail in the header comments in -// "ghost_zone.hh". +// This function "synchronizes" all ghost zones of all patches, i.e. it +// update the ghost-zone values of the specified gridfns via the appropriate +// sequence of symmetry operations and interpatch interpolations. This +// process is described in detail in the header comments in "ghost_zone.hh". // -void patch_system::synchronize_ghost_zones(int ghosted_min_gfn_to_sync, - int ghosted_max_gfn_to_sync) +void patch_system::synchronize(int ghosted_min_gfn_to_sync, + int ghosted_max_gfn_to_sync) { // // Phase 1: @@ -1139,6 +1141,73 @@ void patch_system::synchronize_ghost_zones(int ghosted_min_gfn_to_sync, } //****************************************************************************** + +// +// This function computes the Jacobian of synchronize() into internal +// buffers, taking into account synchronize()'s full 3-phase algorithm. +// +// FIXME FIXME: at the moment we ignore the 3-phase algorithm and just +// pass all the Jacobian operations down to the ghost zones +// +void patch_system::compute_synchronize_Jacobian() +{ + for (int pn = 0 ; pn < N_patches() ; ++pn) + { + patch& p = ith_patch(pn); + // n.b. these loops must use _int_ variables for the loop + // to terminate! + for (int want_min = false ; want_min <= true ; ++want_min) + { + for (int want_rho = false ; want_rho <= true ; ++want_rho) + { + ghost_zone& gz = p.minmax_ang_ghost_zone(want_min, want_rho); + gz.compute_synchronize_Jacobian(); + } + } + } +} + +//****************************************************************************** + +// +// Given that compute_synchronize_Jacobian() has been called, this +// function computes the posn value of the y points in a Jacobian row. +// +// FIXME FIXME: at the moment we ignore the 3-phase algorithm and just +// pass all the operation down to the ghost zones +// +int patch_system::synchronize_Jacobian_y_ipar_posn(const ghost_zone& xgz, + int x_iperp, int x_ipar) + const +{ +return xgz.Jacobian_y_ipar_posn(x_iperp, x_ipar); +} + +//****************************************************************************** + +// +// Given that compute_synchronize_Jacobian() has been called, this +// function computes the Jacobian +// partial synchronize() gridfn(ghosted_gfn, px, x_iperp, x_ipar) +// ------------------------------------------------------------- +// partial gridfn(ghosted_gfn, py, y_iperp, y_posn+y_ipar_m) +// where +// y_iperp = synchronize_Jacobian_y_iperp(xgz, x_iperp) +// y_posn = synchronize_Jacobian_y_ipar_posn(xgz, x_iperp, x_ipar) +// taking into account synchronize()'s full 3-phase algorithm +// +// FIXME FIXME: at the moment we ignore the 3-phase algorithm and just +// pass all the operation down to the ghost zones +// +fp patch_system::synchronize_Jacobian + (const ghost_zone& xgz, int x_iperp, int x_ipar, + int y_ipar_m) + const +{ +return xgz.Jacobian(x_iperp, x_ipar, y_ipar_m); +} + +//****************************************************************************** //****************************************************************************** //****************************************************************************** @@ -1156,89 +1225,89 @@ void patch_system::synchronize_ghost_zones(int ghosted_min_gfn_to_sync, // specified (unknown-grid) radius gridfn. // void patch_system::print_unknown_gridfn - (bool ghosted_flag, int unknown_gfn, - bool print_xyz_flag, bool radius_is_ghosted_flag, - int unknown_radius_gfn, - const char output_file_name[], bool want_ghost_zones) - const +(bool ghosted_flag, int unknown_gfn, + bool print_xyz_flag, bool radius_is_ghosted_flag, + int unknown_radius_gfn, + const char output_file_name[], bool want_ghost_zones) +const { if (want_ghost_zones && !ghosted_flag) - then error_exit(PANIC_EXIT, +then error_exit(PANIC_EXIT, "***** patch_system::print_unknown_gridfn(unknown_gfn=%d):\n" " can't have want_ghost_zones && !ghosted_flag !\n" , - unknown_gfn); /*NOTREACHED*/ + unknown_gfn); /*NOTREACHED*/ if (want_ghost_zones && print_xyz_flag && !radius_is_ghosted_flag) - then error_exit(PANIC_EXIT, +then error_exit(PANIC_EXIT, "***** patch_system::print_unknown_gridfn(unknown_gfn=%d):\n" " can't have want_ghost_zones && print_xyz_flag\n" " && !radius_is_ghosted_flag!\n" " unknown_radius_gfn=%d\n" , - unknown_gfn, - unknown_radius_gfn); /*NOTREACHED*/ + unknown_gfn, + unknown_radius_gfn); /*NOTREACHED*/ FILE *output_fp = std::fopen(output_file_name, "w"); if (output_fp == NULL) - then error_exit(ERROR_EXIT, +then error_exit(ERROR_EXIT, "***** patch_system::print_unknown_gridfn(unknown_gfn=%d):\n" " can't open output file \"%s\"\n!" , - unknown_gfn, - output_file_name); /*NOTREACHED*/ + unknown_gfn, + output_file_name); /*NOTREACHED*/ - for (int pn = 0 ; pn < N_patches() ; ++pn) +for (int pn = 0 ; pn < N_patches() ; ++pn) +{ +const patch& p = ith_patch(pn); + +fprintf(output_fp, "### %s patch\n", p.name()); +fprintf(output_fp, "# %s_gfn=%d\n", + (ghosted_flag ? "ghosted" : "nominal"), unknown_gfn); +fprintf(output_fp, "# dpx = %s\n", p.name_of_dpx()); +fprintf(output_fp, "# dpy = %s\n", p.name_of_dpy()); +fprintf(output_fp, "#\n"); +fprintf(output_fp, + print_xyz_flag + ? "# dpx\tdpy\tgridfn\tglobal_x\tglobal_y\tglobal_z\n" + : "# dpx\tdpy\tgridfn\n"); + + for (int irho = p.effective_min_irho(want_ghost_zones) ; + irho <= p.effective_max_irho(want_ghost_zones) ; + ++irho) { - const patch& p = ith_patch(pn); - - fprintf(output_fp, "### %s patch\n", p.name()); - fprintf(output_fp, "# %s_gfn=%d\n", - (ghosted_flag ? "ghosted" : "nominal"), unknown_gfn); - fprintf(output_fp, "# dpx = %s\n", p.name_of_dpx()); - fprintf(output_fp, "# dpy = %s\n", p.name_of_dpy()); - fprintf(output_fp, "#\n"); + for (int isigma = p.effective_min_isigma(want_ghost_zones) ; + isigma <= p.effective_max_isigma(want_ghost_zones) ; + ++isigma) + { + const fp rho = p.rho_of_irho(irho); + const fp sigma = p.sigma_of_isigma(isigma); + const fp dpx = p.dpx_of_rho_sigma(rho, sigma); + const fp dpy = p.dpy_of_rho_sigma(rho, sigma); fprintf(output_fp, - print_xyz_flag - ? "# dpx\tdpy\tgridfn\tglobal_x\tglobal_y\tglobal_z\n" - : "# dpx\tdpy\tgridfn\n"); - - for (int irho = p.effective_min_irho(want_ghost_zones) ; - irho <= p.effective_max_irho(want_ghost_zones) ; - ++irho) - { - for (int isigma = p.effective_min_isigma(want_ghost_zones) ; - isigma <= p.effective_max_isigma(want_ghost_zones) ; - ++isigma) - { - const fp rho = p.rho_of_irho(irho); - const fp sigma = p.sigma_of_isigma(isigma); - const fp dpx = p.dpx_of_rho_sigma(rho, sigma); - const fp dpy = p.dpy_of_rho_sigma(rho, sigma); + "%g\t%g\t%#.15g", + dpx, dpy, p.unknown_gridfn(ghosted_flag, + unknown_gfn, irho,isigma)); + if (print_xyz_flag) + then { + const fp r = p.unknown_gridfn(radius_is_ghosted_flag, + unknown_radius_gfn, + irho,isigma); + fp local_x, local_y, local_z; + p.xyz_of_r_rho_sigma(r,rho,sigma, + local_x,local_y,local_z); + const fp global_x = global_x_of_local_x(local_x); + const fp global_y = global_y_of_local_y(local_y); + const fp global_z = global_z_of_local_z(local_z); fprintf(output_fp, - "%g\t%g\t%#.15g", - dpx, dpy, p.unknown_gridfn(ghosted_flag, - unknown_gfn, irho,isigma)); - if (print_xyz_flag) - then { - const fp r = p.unknown_gridfn(radius_is_ghosted_flag, - unknown_radius_gfn, - irho,isigma); - fp local_x, local_y, local_z; - p.xyz_of_r_rho_sigma(r,rho,sigma, - local_x,local_y,local_z); - const fp global_x = global_x_of_local_x(local_x); - const fp global_y = global_y_of_local_y(local_y); - const fp global_z = global_z_of_local_z(local_z); - fprintf(output_fp, - "\t%#g\t%#g\t%#g", - global_x, global_y, global_z); - } - fprintf(output_fp, "\n"); - } - fprintf(output_fp, "\n"); + "\t%#g\t%#g\t%#g", + global_x, global_y, global_z); } fprintf(output_fp, "\n"); } + fprintf(output_fp, "\n"); + } +fprintf(output_fp, "\n"); +} std::fclose(output_fp); } @@ -1254,93 +1323,93 @@ std::fclose(output_fp); // ignored. // void patch_system::read_unknown_gridfn(bool ghosted_flag, int unknown_gfn, - const char input_file_name[], - bool want_ghost_zones) + const char input_file_name[], + bool want_ghost_zones) { if (want_ghost_zones && !ghosted_flag) - then error_exit(PANIC_EXIT, +then error_exit(PANIC_EXIT, "***** patch_system::read_unknown_gridfn(unknown_gfn=%d):\n" " can't have want_ghost_zones && !ghosted_flag !\n" , - unknown_gfn); /*NOTREACHED*/ + unknown_gfn); /*NOTREACHED*/ FILE *input_fp = std::fopen(input_file_name, "r"); if (input_fp == NULL) - then error_exit(ERROR_EXIT, +then error_exit(ERROR_EXIT, "***** patch_system::read_unknown_gridfn(unknown_gfn=%d):\n" " can't open input file \"%s\"\n!" , - unknown_gfn, - input_file_name); /*NOTREACHED*/ + unknown_gfn, + input_file_name); /*NOTREACHED*/ int line_number = 1; - for (int pn = 0 ; pn < N_patches() ; ++pn) - { - patch& p = ith_patch(pn); +for (int pn = 0 ; pn < N_patches() ; ++pn) +{ +patch& p = ith_patch(pn); - for (int irho = p.effective_min_irho(want_ghost_zones) ; - irho <= p.effective_max_irho(want_ghost_zones) ; - ++irho) - { - for (int isigma = p.effective_min_isigma(want_ghost_zones) ; - isigma <= p.effective_max_isigma(want_ghost_zones) ; - ++isigma) +for (int irho = p.effective_min_irho(want_ghost_zones) ; + irho <= p.effective_max_irho(want_ghost_zones) ; + ++irho) +{ +for (int isigma = p.effective_min_isigma(want_ghost_zones) ; + isigma <= p.effective_max_isigma(want_ghost_zones) ; + ++isigma) +{ +const fp rho = p.rho_of_irho(irho); +const fp sigma = p.sigma_of_isigma(isigma); +const fp dpx = p.dpx_of_rho_sigma(rho, sigma); +const fp dpy = p.dpy_of_rho_sigma(rho, sigma); + +const int N_buffer = 100; +char buffer[N_buffer]; +// read/discard comments and blank lines + do { - const fp rho = p.rho_of_irho(irho); - const fp sigma = p.sigma_of_isigma(isigma); - const fp dpx = p.dpx_of_rho_sigma(rho, sigma); - const fp dpy = p.dpy_of_rho_sigma(rho, sigma); - - const int N_buffer = 100; - char buffer[N_buffer]; - // read/discard comments and blank lines - do - { - if (std::fgets(buffer, N_buffer, input_fp) == NULL) - then error_exit(ERROR_EXIT, + if (std::fgets(buffer, N_buffer, input_fp) == NULL) + then error_exit(ERROR_EXIT, "***** patch::read_unknown_gridfn(%s patch, unknown_gfn=%d):\n" " I/O error or unexpected end-of-file on input!\n" " at irho=%d of [%d,%d], isigma=%d of [%d,%d]\n" " dpx=%g dpy=%g\n" , - p.name(), unknown_gfn, - irho, p.effective_min_irho(want_ghost_zones), - p.effective_max_irho(want_ghost_zones), - isigma, - p.effective_min_isigma(want_ghost_zones), - p.effective_max_isigma(want_ghost_zones), - dpx, dpy); /*NOTREACHED*/ - ++line_number; - } while ((buffer[0] == '#') || (buffer[0] == '\n')); - - double read_dpx, read_dpy, read_gridfn_value; - if (sscanf(buffer, "%lf %lf %lf", - &read_dpx, &read_dpy, &read_gridfn_value) != 3) - then error_exit(ERROR_EXIT, + p.name(), unknown_gfn, + irho, p.effective_min_irho(want_ghost_zones), + p.effective_max_irho(want_ghost_zones), + isigma, + p.effective_min_isigma(want_ghost_zones), + p.effective_max_isigma(want_ghost_zones), + dpx, dpy); /*NOTREACHED*/ + ++line_number; + } while ((buffer[0] == '#') || (buffer[0] == '\n')); + +double read_dpx, read_dpy, read_gridfn_value; +if (sscanf(buffer, "%lf %lf %lf", + &read_dpx, &read_dpy, &read_gridfn_value) != 3) + then error_exit(ERROR_EXIT, "***** patch::read_unknown_gridfn(%s patch, unknown_gfn=%d):\n" " bad input data at input line %d!\n" , - p.name(), unknown_gfn, - line_number); /*NOTREACHED*/ - if (! ( jtutil::fuzzy<fp>::EQ(read_dpx,dpx) - && jtutil::fuzzy<fp>::EQ(read_dpy,dpy) ) ) - then error_exit(ERROR_EXIT, + p.name(), unknown_gfn, + line_number); /*NOTREACHED*/ +if (! ( jtutil::fuzzy<fp>::EQ(read_dpx,dpx) + && jtutil::fuzzy<fp>::EQ(read_dpy,dpy) ) ) + then error_exit(ERROR_EXIT, "***** patch::read_unknown_gridfn(%s patch, unknown_gfn=%d):\n" " wrong (dpx,dpy) at input line %d!\n" " expected (%g,%g)\n" " read (%g,%g)\n" , - p.name(), unknown_gfn, - line_number, - dpx, dpy, - read_dpx, read_dpy); /*NOTREACHED*/ + p.name(), unknown_gfn, + line_number, + dpx, dpy, + read_dpx, read_dpy); /*NOTREACHED*/ - p.unknown_gridfn(ghosted_flag, - unknown_gfn, irho,isigma) = read_gridfn_value; - } - } +p.unknown_gridfn(ghosted_flag, + unknown_gfn, irho,isigma) = read_gridfn_value; +} +} - } +} std::fclose(input_fp); } diff --git a/src/patch/patch_system.hh b/src/patch/patch_system.hh index 38302bf..0311fce 100644 --- a/src/patch/patch_system.hh +++ b/src/patch/patch_system.hh @@ -242,8 +242,58 @@ public: // i.e. update the ghost-zone values of the specified gridfns // via the appropriate sequence of symmetry operations // and interpatch interpolations - void synchronize_ghost_zones(int ghosted_min_gfn_to_sync, - int ghosted_max_gfn_to_sync); + void synchronize(int ghosted_min_gfn_to_sync, + int ghosted_max_gfn_to_sync); + + + // + // compute Jacobian of synchronize() into internal buffers, + // taking into account synchronize()'s full 3-phase algorithm + // + void compute_synchronize_Jacobian(); + + // + // The following functions access the Jacobian computed by + // compute_synchronize_Jacobian() . Note this API has the + // same implicit assumptions on the Jacobian structure documented + // in the comments in "ghost_zone.hh" immediately following + // ghost_zone::compute_Jacobian() . + // + + // to which patch/edge do the y points in a Jacobian row belong? + patch& synchronize_Jacobian_y_patch(const ghost_zone& xgz) + const + { return xgz.Jacobian_y_patch(); } + const patch_edge& synchronize_Jacobian_y_edge (const ghost_zone& xgz) + const { return xgz.Jacobian_y_edge(); } + + // what is the [min,max] range of m for a Jacobian row? + int synchronize_Jacobian_min_y_ipar_m(const ghost_zone& xgz) + const + { return xgz.Jacobian_min_y_ipar_m(); } + int synchronize_Jacobian_max_y_ipar_m(const ghost_zone& xgz) + const + { return xgz.Jacobian_max_y_ipar_m(); } + + // what is the iperp of the Jacobian y points in their (y) patch? + int synchronize_Jacobian_y_iperp(const ghost_zone& xgz, int x_iperp) + const + { return xgz.Jacobian_y_iperp(x_iperp); } + + // what is the posn value of the y points in this Jacobian row? + int synchronize_Jacobian_y_ipar_posn(const ghost_zone& xgz, + int x_iperp, int x_ipar) const; + + // what is the Jacobian + // partial synchronize() gridfn(ghosted_gfn, px, x_iperp, x_ipar) + // ------------------------------------------------------------- + // partial gridfn(ghosted_gfn, py, y_iperp, y_posn+y_ipar_m) + // where + // y_iperp = Jacobian_y_iperp(x_iperp) + // y_posn = Jacobian_y_ipar_posn(x_iperp, x_ipar) + // taking into account synchronize()'s full 3-phase algorithm + fp synchronize_Jacobian(const ghost_zone& xgz, int x_iperp, int x_ipar, + int y_ipar_m) const; // diff --git a/src/patch/test_coords2.cc b/src/patch/test_coords2.cc index 2a1d41f..0dcf056 100644 --- a/src/patch/test_coords2.cc +++ b/src/patch/test_coords2.cc @@ -28,7 +28,7 @@ using namespace local_coords; namespace { void test_r_mu_nu_phi(fp x, fp y, fp z); void test_r_theta_phi(fp x, fp y, fp z); - }; + } //****************************************************************************** diff --git a/src/patch/test_patch_system.cc b/src/patch/test_patch_system.cc index 5866a9d..27fe933 100644 --- a/src/patch/test_patch_system.cc +++ b/src/patch/test_patch_system.cc @@ -130,7 +130,7 @@ fp finite_diff_fn(const patch& p, int ghosted_gfn_src, int which_derivs, int irho, int isigma); fp analytic_deriv_fn(fp rho, fp sigma, int which_derivs); - }; + } //****************************************************************************** //****************************************************************************** @@ -199,7 +199,7 @@ else if (STRING_EQUAL(which_test, "synchronize")) setup_sym_fn_xyz(ps, test_fn_copy_gfn, true); ps.print_ghosted_gridfn(test_fn_copy_gfn, "test_fn_copy.dat"); - ps.synchronize_ghost_zones(test_fn_gfn, test_fn_gfn); + ps.synchronize(test_fn_gfn, test_fn_gfn); ps.print_ghosted_gridfn(test_fn_gfn, "test_fn_sync.dat"); ghosted_gridfn_minus(ps, @@ -246,8 +246,7 @@ CCTK_VInfo(CCTK_THORNSTRING, "destroying patch system"); // // This function tests the computation of the Jacobian of the -// patch_system::synchronize_ghost_zones() operation. In outline, it -// does the following: +// patch_system::synchronize() operation. In outline, it does the following: // // set up a test function in test_gfn on the nominal grid // synchronize test_gfn @@ -311,7 +310,7 @@ void test_synchronize_Jacobians(patch_system& ps, CCTK_VInfo(CCTK_THORNSTRING, "testing synchronize() Jacobian..."); setup_sym_fn_xyz(ps, test_gfn, false); -ps.synchronize_ghost_zones(test_fn_gfn, test_fn_gfn); +ps.synchronize(test_fn_gfn, test_fn_gfn); ps.print_ghosted_gridfn(test_fn_gfn, "test_fn.dat"); setup_sym_fn_xyz(ps, NP_test_gfn, false); @@ -404,7 +403,7 @@ fprintf(fileptr, "# column 17 = Jacobian error\n"); yp.ghosted_gridfn(NP_test_gfn, y_irho,y_isigma) += perturbation_amplitude; - ps.synchronize_ghost_zones(NP_test_gfn, NP_test_gfn); + ps.synchronize(NP_test_gfn, NP_test_gfn); const fp NP_Jacobian = ( xp.ghosted_gridfn(NP_test_gfn, x_irho,x_isigma) - xp.ghosted_gridfn( test_gfn, x_irho,x_isigma) ) @@ -858,7 +857,7 @@ default: int(type)); /*NOTREACHED*/ } } - }; + } //****************************************************************************** @@ -871,7 +870,7 @@ fp fn_xyz(fp x, fp y, fp z) return (x*(x+0.238) + 2.417*y*(y-0.917) + 1.38*z*(z-0.472)) * tanh(jtutil::pow3(cos(z))); } - }; + } //****************************************************************************** //****************************************************************************** @@ -886,7 +885,7 @@ fp fn_rho_sigma(fp rho, fp sigma) { return exp(sin(1.38*rho)) * tanh(0.17+0.83*jtutil::pow2(sin(sigma))); } - }; + } //****************************************************************************** @@ -927,7 +926,7 @@ if (which_derivs & which_deriv_sigma_sigma) return sum; } - }; + } //****************************************************************************** @@ -989,4 +988,4 @@ if (which_derivs & which_deriv_sigma_sigma) return sum; } - }; + } |