diff options
author | eschnett <> | 2001-03-01 11:40:00 +0000 |
---|---|---|
committer | eschnett <> | 2001-03-01 11:40:00 +0000 |
commit | 310f0ea48d18866b773136aed11200b6eda6378b (patch) | |
tree | 445d3e34ce8b89812994b6614f7bc9f4acbc7fe2 /CarpetDev/CarpetJacobi |
Initial revision
darcs-hash:20010301114010-f6438-12fb8a9ffcc80e86c0a97e37b5b0dae0dbc59b79.gz
Diffstat (limited to 'CarpetDev/CarpetJacobi')
-rw-r--r-- | CarpetDev/CarpetJacobi/README | 11 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/doc/documentation.tex | 144 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/interface.ccl | 9 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/par/charge_te_cjac.par | 60 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/par/charge_te_cjac_2.par | 60 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/param.ccl | 32 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/schedule.ccl | 7 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/src/Jacobi.cc | 536 | ||||
-rw-r--r-- | CarpetDev/CarpetJacobi/src/make.code.defn | 9 |
9 files changed, 868 insertions, 0 deletions
diff --git a/CarpetDev/CarpetJacobi/README b/CarpetDev/CarpetJacobi/README new file mode 100644 index 000000000..74967b13f --- /dev/null +++ b/CarpetDev/CarpetJacobi/README @@ -0,0 +1,11 @@ +CVS info : $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/README,v 1.1 2003/09/02 14:35:57 schnetter Exp $ + +Cactus Code Thorn CarpetJacobi +Thorn Author(s) : Erik Schnetter <schnetter@uni-tuebingen.de> +Thorn Maintainer(s) : Erik Schnetter <schnetter@uni-tuebingen.de> +-------------------------------------------------------------------------- + +Purpose of the thorn: + +Solve an elliptic equation using Jacobi iterations with varying step +size. diff --git a/CarpetDev/CarpetJacobi/doc/documentation.tex b/CarpetDev/CarpetJacobi/doc/documentation.tex new file mode 100644 index 000000000..11d9ffd8d --- /dev/null +++ b/CarpetDev/CarpetJacobi/doc/documentation.tex @@ -0,0 +1,144 @@ +% *======================================================================* +% Cactus Thorn template for ThornGuide documentation +% Author: Ian Kelley +% Date: Sun Jun 02, 2002 +% $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/doc/documentation.tex,v 1.1 2003/09/02 14:35:57 schnetter Exp $ +% +% Thorn documentation in the latex file doc/documentation.tex +% will be included in ThornGuides built with the Cactus make system. +% The scripts employed by the make system automatically include +% pages about variables, parameters and scheduling parsed from the +% relevant thorn CCL files. +% +% This template contains guidelines which help to assure that your +% documentation will be correctly added to ThornGuides. More +% information is available in the Cactus UsersGuide. +% +% Guidelines: +% - Do not change anything before the line +% % START CACTUS THORNGUIDE", +% except for filling in the title, author, date etc. fields. +% - Each of these fields should only be on ONE line. +% - Author names should be separated with a \\ or a comma +% - You can define your own macros, but they must appear after +% the START CACTUS THORNGUIDE line, and must not redefine standard +% latex commands. +% - To avoid name clashes with other thorns, 'labels', 'citations', +% 'references', and 'image' names should conform to the following +% convention: +% ARRANGEMENT_THORN_LABEL +% For example, an image wave.eps in the arrangement CactusWave and +% thorn WaveToyC should be renamed to CactusWave_WaveToyC_wave.eps +% - Graphics should only be included using the graphicx package. +% More specifically, with the "\includegraphics" command. Do +% not specify any graphic file extensions in your .tex file. This +% will allow us (later) to create a PDF version of the ThornGuide +% via pdflatex. +% - References should be included with the latex "\bibitem" command. +% - Use \begin{abstract}...\end{abstract} instead of \abstract{...} +% - Do not use \appendix, instead include any appendices you need as +% standard sections. +% - For the benefit of our Perl scripts, and for future extensions, +% please use simple latex. +% +% *======================================================================* +% +% Example of including a graphic image: +% \begin{figure}[ht] +% \begin{center} +% \includegraphics[width=6cm]{MyArrangement_MyThorn_MyFigure} +% \end{center} +% \caption{Illustration of this and that} +% \label{MyArrangement_MyThorn_MyLabel} +% \end{figure} +% +% Example of using a label: +% \label{MyArrangement_MyThorn_MyLabel} +% +% Example of a citation: +% \cite{MyArrangement_MyThorn_Author99} +% +% Example of including a reference +% \bibitem{MyArrangement_MyThorn_Author99} +% {J. Author, {\em The Title of the Book, Journal, or periodical}, 1 (1999), +% 1--16. {\tt http://www.nowhere.com/}} +% +% *======================================================================* + +% If you are using CVS use this line to give version information +% $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/doc/documentation.tex,v 1.1 2003/09/02 14:35:57 schnetter Exp $ + +\documentclass{article} + +% Use the Cactus ThornGuide style file +% (Automatically used from Cactus distribution, if you have a +% thorn without the Cactus Flesh download this from the Cactus +% homepage at www.cactuscode.org) +\usepackage{../../../../doc/latex/cactus} + +\begin{document} + +% The author of the documentation +\author{Erik Schnetter \textless schnetter@uni-tuebingen.de\textgreater} + +% The title of the document (not necessarily the name of the Thorn) +\title{} + +% the date your document was last changed, if your document is in CVS, +% please use: +% \date{$ $Date: 2003/09/02 14:35:57 $ $} +\date{August 31 2003} + +\maketitle + +% Do not delete next line +% START CACTUS THORNGUIDE + +% Add all definitions used in this documentation here +% \def\mydef etc + +% Add an abstract for this thorn's documentation +\begin{abstract} + +\end{abstract} + +% The following sections are suggestive only. +% Remove them or add your own. + +\section{Introduction} + +\section{Physical System} + +\section{Numerical Implementation} + +\section{Using This Thorn} + +\subsection{Obtaining This Thorn} + +\subsection{Basic Usage} + +\subsection{Special Behaviour} + +\subsection{Interaction With Other Thorns} + +\subsection{Examples} + +\subsection{Support and Feedback} + +\section{History} + +\subsection{Thorn Source Code} + +\subsection{Thorn Documentation} + +\subsection{Acknowledgements} + + +\begin{thebibliography}{9} + +\end{thebibliography} + +% Do not delete next line +% END CACTUS THORNGUIDE + +\end{document} diff --git a/CarpetDev/CarpetJacobi/interface.ccl b/CarpetDev/CarpetJacobi/interface.ccl new file mode 100644 index 000000000..6b61da31a --- /dev/null +++ b/CarpetDev/CarpetJacobi/interface.ccl @@ -0,0 +1,9 @@ +# Interface definition for thorn CarpetJacobi +# $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/interface.ccl,v 1.1 2003/09/02 14:35:57 schnetter Exp $ + +IMPLEMENTS: CarpetJacobi + +INHERITS: TATelliptic + +USES INCLUDE HEADER: carpet.hh +USES INCLUDE HEADER: TATelliptic.h diff --git a/CarpetDev/CarpetJacobi/par/charge_te_cjac.par b/CarpetDev/CarpetJacobi/par/charge_te_cjac.par new file mode 100644 index 000000000..8db9c4cf6 --- /dev/null +++ b/CarpetDev/CarpetJacobi/par/charge_te_cjac.par @@ -0,0 +1,60 @@ +# $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/par/charge_te_cjac.par,v 1.4 2004/03/23 11:59:20 schnetter Exp $ +# Erik Schnetter <schnetter@uni-tuebingen.de> + +ActiveThorns = "Boundary CartGrid3D CoordBase SymBase CarpetIOASCII IOBasic IOUtil Time Carpet CarpetLib CarpetRegrid CarpetReduce NaNCatcher IDScalarWave WaveToyC IDSWTEsimple TATelliptic CarpetJacobi" + +!DESC "Charged sphere initial data, solved with TATelliptic/CarpetJacobi" + +cactus::cctk_full_warnings = yes +cactus::cctk_timer_output = full + +#Cactus::cctk_itlast = 10 +Cactus::cctk_itlast = 0 + +Time::dtfac = 0.5 + +driver::global_nsize = 21 +#driver::global_nsize = 41 + +Carpet::verbose = yes +#Carpet::veryverbose = yes + +Carpet::max_refinement_levels = 2 +#Carpet::prolongation_order_space = 3 +Carpet::prolongation_order_time = 2 +Carpet::init_3_timelevels = yes + +CarpetRegrid::refinement_levels = 1 +CarpetRegrid::refined_regions = manual-gridpoint-list +CarpetRegrid::gridpoints = "[[ ([1,1,1]:[20,20,20]:[1,1,1]) ]]" +CarpetRegrid::outerbounds = "[[ [[1,0],[1,0],[1,0]] ]]" + +grid::type = byspacing +grid::domain = octant +grid::dxyz = 1.2 +grid::avoid_origin = no + +IDScalarWave::initial_data = charge-TATelliptic-simple +IDSWTEsimple::solver = CarpetJacobi +#IDSWTEsimple::options = "maxiters=10000 minerror=1e-4 factor=1e-2" +#IDSWTEsimple::options = "maxiters=100000 minerror=1e-8 factor=1e-2" +IDSWTEsimple::options = "maxiters=10000 minerror=1e-8" +IDSWTEsimple::radius = 5.5 +IDSWTEsimple::charge = 1.0 + +WaveToyC::bound = radiation + +CarpetJacobi::verbose = yes + +IO::out_dir = "charge_te_cjac" +IO::out_fileinfo = none + +IOBasic::outInfo_every = 1 +IOBasic::outInfo_vars = "wavetoy::phi IDSWTEsimple::residual" + +IOBasic::outScalar_every = 1 +IOBasic::outScalar_vars = "wavetoy::phi IDSWTEsimple::residual" +IOBasic::outScalar_style = "gnuplot" + +CarpetIOASCII::out1D_every = 1 +CarpetIOASCII::out1D_vars = "wavetoy::phi IDSWTEsimple::residual" diff --git a/CarpetDev/CarpetJacobi/par/charge_te_cjac_2.par b/CarpetDev/CarpetJacobi/par/charge_te_cjac_2.par new file mode 100644 index 000000000..b26fe4d48 --- /dev/null +++ b/CarpetDev/CarpetJacobi/par/charge_te_cjac_2.par @@ -0,0 +1,60 @@ +# $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/par/charge_te_cjac_2.par,v 1.4 2004/03/23 11:59:20 schnetter Exp $ +# Erik Schnetter <schnetter@uni-tuebingen.de> + +ActiveThorns = "Boundary CartGrid3D CoordBase SymBase CarpetIOASCII IOBasic IOUtil Time Carpet CarpetLib CarpetRegrid CarpetReduce NaNCatcher IDScalarWave WaveToyC IDSWTEsimple TATelliptic CarpetJacobi" + +!DESC "Charged sphere initial data, solved with TATelliptic/CarpetJacobi" + +cactus::cctk_full_warnings = yes +cactus::cctk_timer_output = full + +#Cactus::cctk_itlast = 10 +Cactus::cctk_itlast = 0 + +Time::dtfac = 0.5 + +driver::global_nsize = 21 +#driver::global_nsize = 41 + +Carpet::verbose = yes +#Carpet::veryverbose = yes + +Carpet::max_refinement_levels = 2 +#Carpet::prolongation_order_space = 3 +Carpet::prolongation_order_time = 2 +Carpet::init_3_timelevels = yes + +CarpetRegrid::refinement_levels = 2 +CarpetRegrid::refined_regions = manual-gridpoint-list +CarpetRegrid::gridpoints = "[[ ([1,1,1]:[20,20,20]:[1,1,1]) ]]" +CarpetRegrid::outerbounds = "[[ [[1,0],[1,0],[1,0]] ]]" + +grid::type = byspacing +grid::domain = octant +grid::dxyz = 1.2 +grid::avoid_origin = no + +IDScalarWave::initial_data = charge-TATelliptic-simple +IDSWTEsimple::solver = CarpetJacobi +#IDSWTEsimple::options = "maxiters=10000 minerror=1e-4 factor=1e-2" +#IDSWTEsimple::options = "maxiters=100000 minerror=1e-8 factor=1e-2" +IDSWTEsimple::options = "maxiters=10000 minerror=1e-8" +IDSWTEsimple::radius = 5.5 +IDSWTEsimple::charge = 1.0 + +WaveToyC::bound = radiation + +CarpetJacobi::verbose = yes + +IO::out_dir = "charge_te_cjac_2" +IO::out_fileinfo = none + +IOBasic::outInfo_every = 1 +IOBasic::outInfo_vars = "wavetoy::phi IDSWTEsimple::residual" + +IOBasic::outScalar_every = 1 +IOBasic::outScalar_vars = "wavetoy::phi IDSWTEsimple::residual" +IOBasic::outScalar_style = "gnuplot" + +CarpetIOASCII::out1D_every = 1 +CarpetIOASCII::out1D_vars = "wavetoy::phi IDSWTEsimple::residual" diff --git a/CarpetDev/CarpetJacobi/param.ccl b/CarpetDev/CarpetJacobi/param.ccl new file mode 100644 index 000000000..bdeecf41b --- /dev/null +++ b/CarpetDev/CarpetJacobi/param.ccl @@ -0,0 +1,32 @@ +# Parameter definitions for thorn CarpetJacobi +# $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/param.ccl,v 1.2 2004/01/25 14:57:29 schnetter Exp $ + +BOOLEAN verbose "Produce log output while running" STEERABLE=always +{ +} "no" + +BOOLEAN veryverbose "Produce much log output while running" STEERABLE=always +{ +} "no" + +CCTK_INT outevery "Produce output every n iterations" STEERABLE=always +{ + 1:* :: "" +} 1 + +CCTK_INT outeveryseconds "Produce output every n seconds" STEERABLE=always +{ + 0:* :: "" +} 10 + + + +CCTK_INT solve_minlevel "First level on which to solve" STEERABLE=always +{ + 0:* :: "" +} 0 + +CCTK_INT reflevelpower "Power of the refinement factor" STEERABLE=always +{ + 0:* :: "" +} 2 diff --git a/CarpetDev/CarpetJacobi/schedule.ccl b/CarpetDev/CarpetJacobi/schedule.ccl new file mode 100644 index 000000000..009b40f7a --- /dev/null +++ b/CarpetDev/CarpetJacobi/schedule.ccl @@ -0,0 +1,7 @@ +# Schedule definitions for thorn CarpetJacobi +# $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/schedule.ccl,v 1.1 2003/09/02 14:35:57 schnetter Exp $ + +SCHEDULE CarpetJacobi_register AT startup +{ + LANG: C +} "Register the elliptic solver" diff --git a/CarpetDev/CarpetJacobi/src/Jacobi.cc b/CarpetDev/CarpetJacobi/src/Jacobi.cc new file mode 100644 index 000000000..c326b66cd --- /dev/null +++ b/CarpetDev/CarpetJacobi/src/Jacobi.cc @@ -0,0 +1,536 @@ +// $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/src/Jacobi.cc,v 1.3 2004/01/25 14:57:29 schnetter Exp $ + +#include <cassert> +#include <cmath> +#include <cstdio> +#include <ctime> +#include <iostream> +#include <vector> + +#include "cctk.h" +#include "cctk_Arguments.h" +#include "cctk_Parameters.h" + +#include "util_ErrorCodes.h" +#include "util_Table.h" + +#include "TATelliptic.h" + +#include "carpet.hh" + +#include "th.hh" + + + +namespace Carpet { + // TODO: fix this + void CycleTimeLevels (const cGH* cctkGH); + void Restrict (const cGH* cctkGH); +}; + + + +namespace CarpetJacobi { + + using namespace std; + using namespace Carpet; + + + + extern "C" { + void CarpetJacobi_register (); + } + + int CarpetJacobi_solve (const cGH * const cctkGH, + const int * const var, + const int * const res, + const int nvars, + const int options_table, + const calcfunc calcres, + const calcfunc applybnds, + void * const userdata); + + + + void CarpetJacobi_register () + { + int const ierr = TATelliptic_RegisterSolver + (CarpetJacobi_solve, "CarpetJacobi"); + assert (!ierr); + } + + + + int CarpetJacobi_solve (const cGH * const cctkGH, + const int * const var, + const int * const res, + const int nvars, + const int options_table, + const calcfunc calcres, + const calcfunc applybnds, + void * const userdata) + { + DECLARE_CCTK_PARAMETERS; + + // Error control + int ierr; + + if (! CCTK_IsThornActive(CCTK_THORNSTRING)) { + CCTK_WARN (0, "Thorn " CCTK_THORNSTRING " has not been activated. It is therefore not possible to call CarpetJacobi_solve."); + } + + // Check arguments + assert (cctkGH); + + assert (nvars > 0); + assert (var); + assert (res); + for (int n=0; n<nvars; ++n) { + assert (var[n] >= 0 && var[n] < CCTK_NumVars()); + assert (CCTK_GroupTypeFromVarI(var[n]) == CCTK_GF); + assert (CCTK_GroupDimFromVarI(var[n]) == dim); + assert (CCTK_VarTypeI(var[n]) == CCTK_VARIABLE_REAL); + assert (CCTK_QueryGroupStorageI(cctkGH, + CCTK_GroupIndexFromVarI(var[n]))); + } + for (int n=0; n<nvars; ++n) { + assert (res[n] >= 0 && res[n] < CCTK_NumVars()); + assert (CCTK_GroupTypeFromVarI(res[n]) == CCTK_GF); + assert (CCTK_GroupDimFromVarI(res[n]) == dim); + assert (CCTK_VarTypeI(res[n]) == CCTK_VARIABLE_REAL); + assert (CCTK_QueryGroupStorageI(cctkGH, + CCTK_GroupIndexFromVarI(res[n]))); + } + for (int n=0; n<nvars; ++n) { + assert (var[n] != res[n]); + for (int nn=0; nn<n; ++nn) { + assert (var[nn] != var[n]); + assert (var[nn] != res[n]); + assert (res[nn] != var[n]); + assert (res[nn] != res[n]); + } + } + + + + assert (options_table >= 0); + + assert (calcres); + assert (applybnds); + + // Get options from options table + CCTK_INT maxiters = 10000; + CCTK_REAL minerror = 1e-8; + CCTK_REAL factor = 1.0e-2; // slow start + CCTK_REAL minfactor = 1.0e-8; + CCTK_REAL maxfactor = 1.0; + CCTK_REAL acceleration = 1.2; // slow acceleration + CCTK_REAL deceleration = 0.1; // emergency brake + vector<CCTK_REAL> factors (nvars); + for (int n=0; n<nvars; ++n) { + factors[n] = 1.0; + } + + ierr = Util_TableGetInt (options_table, &maxiters, "maxiters"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetReal (options_table, &minerror, "minerror"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetReal (options_table, &factor, "factor"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetReal (options_table, &minfactor, "minfactor"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetReal (options_table, &maxfactor, "maxfactor"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetReal (options_table, &acceleration, "acceleration"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetReal (options_table, &deceleration, "deceleration"); + assert (ierr==1 || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + ierr = Util_TableGetRealArray (options_table, + nvars, &factors[0], "factors"); + assert (ierr==nvars || ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY); + + assert (maxiters >= 0); + assert (minerror >= 0); + assert (factor > 0); + assert (minfactor > 0 && minfactor <= factor); + assert (maxfactor >= factor); + assert (acceleration >= 1); + assert (deceleration > 0 && deceleration <= 1); + for (int n=0; n<nvars; ++n) { + assert (factors[n] != 0); + } + + + + assert (is_global_mode() || is_level_mode()); + + // The level to solve on + const int solve_level = is_level_mode() ? reflevel : reflevels-1; + + if (solve_level < solve_minlevel) { + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Did not solve because the level is too coarse."); + } + Util_TableSetInt (options_table, 0, "iters"); + Util_TableSetReal (options_table, -1.0, "error"); + + // Return as if the solving had not converged + return -1; + } + +#warning "TODO: assert that all levels are at the same time" + + // Switch to global mode + BEGIN_GLOBAL_MODE(cctkGH) { + + // Reset the initial data time + global_time = 0; + delta_time = 1; + * const_cast<CCTK_REAL *> (& cctkGH->cctk_time) = global_time; + * const_cast<CCTK_REAL *> (& cctkGH->cctk_delta_time) = delta_time; + BEGIN_REFLEVEL_LOOP(cctkGH) { + * const_cast<CCTK_REAL *> (& cctkGH->cctk_time) = global_time; + for (int m=0; m<maps; ++m) { + vtt[m]->set_time (reflevel, mglevel, 0); + vtt[m]->set_delta + (reflevel, mglevel, 1.0 / ipow(reflevelfact, reflevelpower)); + } + } END_REFLEVEL_LOOP; + + + + // Init statistics + vector<CCTK_REAL> norm_counts (solve_level+1); + vector<CCTK_REAL> norm_l2s (solve_level+1); + CCTK_REAL norm2 = HUGE_VAL; + CCTK_REAL speed = 0.0; + CCTK_REAL throttle = 1.0; + bool did_hit_min = false; + bool did_hit_max = false; + const time_t starttime = time(0); + time_t nexttime = starttime; + + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Solving through adaptive Jacobi iterations"); + } + + const int icoarsestep + = ipow (mglevelfact * maxreflevelfact, reflevelpower); + const int istep + = ipow (mglevelfact * maxreflevelfact / ipow(reffact, solve_level), + reflevelpower); + int iter = istep; + for (;; iter+=istep) { + + global_time = 1.0 * iter / ipow(maxreflevelfact, reflevelpower); + * const_cast<CCTK_REAL *> (& cctkGH->cctk_time) = global_time; +// cout << "CJ global iter " << iter << " time " << global_time << flush << endl; + + // Calculate residual, smooth, and apply boundary conditions + ierr = 0; + BEGIN_REFLEVEL_LOOP(cctkGH) { + const int do_every + = ipow (mglevelfact * (maxreflevelfact/reflevelfact), + reflevelpower); + if (reflevel <= solve_level && (iter-istep) % do_every == 0) { + + // Advance time + for (int m=0; m<maps; ++m) { + vtt[m]->advance_time (reflevel, mglevel); + } + * const_cast<CCTK_REAL *> (& cctkGH->cctk_time) + = (1.0 * (iter - istep + do_every) + / ipow(maxreflevelfact, reflevelpower)); + CycleTimeLevels (cctkGH); +// cout << "CJ residual iter " << iter << " reflevel " << reflevel << " time " << cctkGH->cctk_time << flush << endl; + + // Calculate residual + BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { + BEGIN_LOCAL_COMPONENT_LOOP(cctkGH, CCTK_GF) { + if (! ierr) { + ierr = calcres (cctkGH, options_table, userdata); + } + } END_LOCAL_COMPONENT_LOOP; + } END_MAP_LOOP; + + // Smooth and apply boundary conditions + CCTK_REAL levfac = 0; + for (int d=0; d<dim; ++d) { + levfac += 1 / + pow (cctkGH->cctk_delta_space[d] / cctkGH->cctk_levfac[d], 2); + } + levfac = 1 / levfac; + + BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { + BEGIN_LOCAL_COMPONENT_LOOP(cctkGH, CCTK_GF) { + if (! ierr) { + + for (int n=0; n<nvars; ++n) { + CCTK_REAL * restrict varptr + = (CCTK_REAL *)CCTK_VarDataPtrI (cctkGH, 0, var[n]); + assert (varptr); + const CCTK_REAL * restrict resptr + = (const CCTK_REAL *)CCTK_VarDataPtrI(cctkGH, 0, res[n]); + assert (resptr); + assert (resptr != varptr); + const CCTK_REAL fac = factor * factors[n] * levfac; + assert (cctkGH->cctk_dim == 3); + for (int k=cctkGH->cctk_nghostzones[2]; + k<cctkGH->cctk_lsh[2]-cctkGH->cctk_nghostzones[2]; + ++k) { + for (int j=cctkGH->cctk_nghostzones[1]; + j<cctkGH->cctk_lsh[1]-cctkGH->cctk_nghostzones[1]; + ++j) { + for (int i=cctkGH->cctk_nghostzones[0]; + i<cctkGH->cctk_lsh[0]-cctkGH->cctk_nghostzones[0]; + ++i) { + const int ind = CCTK_GFINDEX3D(cctkGH, i, j, k); + varptr[ind] += fac * resptr[ind]; + } + } + } + } // for n + + // Apply boundary conditions + ierr = applybnds (cctkGH, options_table, userdata); + + } + } END_LOCAL_COMPONENT_LOOP; + } END_MAP_LOOP; + + } + } END_REFLEVEL_LOOP; + + if (ierr) { + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Residual calculation or boundary conditions reported error; aborting solver."); + } + Util_TableSetInt (options_table, iter, "iters"); + Util_TableDeleteKey (options_table, "error"); + goto done; + } + + // Restrict and calculate norm + ierr = 0; + BEGIN_REVERSE_REFLEVEL_LOOP(cctkGH) { + const int do_every + = ipow (mglevelfact * (maxreflevelfact/reflevelfact), + reflevelpower); + if (reflevel <= solve_level && iter % do_every == 0) { + +// cout << "CJ restrict iter " << iter << " reflevel " << reflevel << " time " << cctkGH->cctk_time << flush << endl; + + if (! ierr) { + if (reflevel < solve_level) { + Restrict (cctkGH); + } + } + + BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { + BEGIN_LOCAL_COMPONENT_LOOP(cctkGH, CCTK_GF) { + if (! ierr) { + ierr = applybnds (cctkGH, options_table, userdata); + } + } END_LOCAL_COMPONENT_LOOP; + } END_MAP_LOOP; + + // Initialise norm + CCTK_REAL norm_count = 0; + CCTK_REAL norm_l2 = 0; + + BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { + BEGIN_LOCAL_COMPONENT_LOOP(cctkGH, CCTK_GF) { + if (! ierr) { + + // Calculate norm + for (int n=0; n<nvars; ++n) { + const CCTK_REAL * restrict resptr + = (const CCTK_REAL *)CCTK_VarDataPtrI(cctkGH, 0, res[n]); + assert (resptr); + const CCTK_REAL fac = factors[n]; + assert (cctkGH->cctk_dim == 3); + for (int k=cctkGH->cctk_nghostzones[2]; + k<cctkGH->cctk_lsh[2]-cctkGH->cctk_nghostzones[2]; + ++k) { + for (int j=cctkGH->cctk_nghostzones[1]; + j<cctkGH->cctk_lsh[1]-cctkGH->cctk_nghostzones[1]; + ++j) { + for (int i=cctkGH->cctk_nghostzones[0]; + i<cctkGH->cctk_lsh[0]-cctkGH->cctk_nghostzones[0]; + ++i) { + const int ind = CCTK_GFINDEX3D(cctkGH, i, j, k); + ++norm_count; + // TODO: scale the norm by the resolution? + norm_l2 += pow(fac * resptr[ind], 2); + } + } + } + } // for n + + } + } END_LOCAL_COMPONENT_LOOP; + } END_MAP_LOOP; + + const int sum_handle = CCTK_ReductionArrayHandle ("sum"); + assert (sum_handle >= 0); + CCTK_REAL reduce_in[2], reduce_out[2]; + reduce_in[0] = norm_count; + reduce_in[1] = norm_l2; + ierr = CCTK_ReduceLocArrayToArray1D + (cctkGH, -1, sum_handle, reduce_in, reduce_out, 2, + CCTK_VARIABLE_REAL); + norm_counts.at(reflevel) = reduce_out[0]; + norm_l2s.at(reflevel) = reduce_out[1]; + +#warning "TODO" +#if 0 + CCTK_OutputVarAs (cctkGH, "WaveToyFO::phi", "phi-ell"); + CCTK_OutputVarAs (cctkGH, "IDSWTEsimpleFO::residual", "residual-ell"); +#endif + + } + } END_REVERSE_REFLEVEL_LOOP; + + if (ierr) { + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Residual calculation or boundary conditions reported error; aborting solver."); + } + Util_TableSetInt (options_table, iter, "iters"); + Util_TableDeleteKey (options_table, "error"); + goto done; + } + + // Save old norm + const CCTK_REAL old_norm2 = norm2; + + // Calculate new norm + CCTK_REAL norm_count = 0; + CCTK_REAL norm_l2 = 0; + for (int rl=0; rl<=solve_level; ++rl) { + norm_count += norm_counts[rl]; + norm_l2 += norm_l2s[rl]; + } + norm2 = sqrt(norm_l2 / norm_count); + + // Calculate convergence speed + speed = old_norm2 / norm2; + + // Log output + if (verbose || veryverbose) { + const time_t currenttime = time(0); + if ((iter % icoarsestep == 0 && iter >= maxiters) +#if HAVE_ISNAN + || isnan(norm2) +#endif + || norm2 <= minerror + || (iter % outevery == 0 && currenttime >= nexttime)) { + if (verbose || veryverbose) { + if (did_hit_min) { + CCTK_VInfo (CCTK_THORNSTRING, + "Convergence factor became too small: artificially kept at minfactor (may lead to instability)"); + } + if (did_hit_max) { + CCTK_VInfo (CCTK_THORNSTRING, + "Convergence factor became too large: artificially kept at maxfactor (may lead to slower convergence)"); + } + did_hit_min = false; + did_hit_max = false; + } + if (veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Iteration %d, time %g, factor %g, throttle %g, residual %g, speed %g", + iter, double(currenttime-starttime), + double(factor), double(throttle), double(norm2), + double(speed)); + } else { + CCTK_VInfo (CCTK_THORNSTRING, + "Iteration %d, time %g, residual %g", + iter, double(currenttime-starttime), double(norm2)); + } + if (outeveryseconds > 0) { + while (nexttime <= currenttime) nexttime += outeveryseconds; + } + } + } + +#if HAVE_ISNAN + // Exit if things go bad + if (isnan(norm2)) { + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Encountered NaN. Aborting solver."); + } + break; + } +#endif + + // Return when desired accuracy is reached + if (norm2 <= minerror) { + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, "Done solving."); + } + Util_TableSetInt (options_table, iter, "iters"); + Util_TableSetReal (options_table, norm2, "error"); + ierr = 0; + goto done; + } + + // Exit if the maximum number of iterations has been reached + if (iter % icoarsestep == 0 && iter >= maxiters) { + break; + } + + // Adjust speed + if (speed > 1.0) { + throttle = acceleration; + } else { + throttle = deceleration; + } + factor *= throttle; + if (factor < minfactor) { + did_hit_min = true; + factor = minfactor; + } + if (factor > maxfactor) { + did_hit_max = true; + factor = maxfactor; + } + + } // for iter + + // Did not solve + if (verbose || veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, "Did not converge."); + } + Util_TableSetInt (options_table, iter, "iters"); + Util_TableSetReal (options_table, norm2, "error"); + ierr = -1; + + done: ; + + + + // Reset the initial time +#warning "TODO: reset the initial time a bit more intelligently" + global_time = 0; + delta_time = 1; + * const_cast<CCTK_REAL *> (& cctkGH->cctk_time) = global_time; + * const_cast<CCTK_REAL *> (& cctkGH->cctk_delta_time) = delta_time; + BEGIN_REFLEVEL_LOOP(cctkGH) { + * const_cast<CCTK_REAL *> (& cctkGH->cctk_time) = global_time; + for (int m=0; m<maps; ++m) { + vtt[m]->set_time (reflevel, mglevel, 0); + vtt[m]->set_delta (reflevel, mglevel, 1.0 / reflevelfact); + } + } END_REFLEVEL_LOOP; + + } END_GLOBAL_MODE; + + return ierr; + } + +} // namespace CarpetJacobi diff --git a/CarpetDev/CarpetJacobi/src/make.code.defn b/CarpetDev/CarpetJacobi/src/make.code.defn new file mode 100644 index 000000000..efd1ad4c4 --- /dev/null +++ b/CarpetDev/CarpetJacobi/src/make.code.defn @@ -0,0 +1,9 @@ +# Main make.code.defn file for thorn CarpetJacobi +# $Header: /home/eschnett/C/carpet/Carpet/CarpetDev/CarpetJacobi/src/make.code.defn,v 1.1 2003/09/02 14:35:58 schnetter Exp $ + +# Source files in this directory +SRCS = Jacobi.cc + +# Subdirectories containing source files +SUBDIRS = + |