diff options
author | Ian Hinder <ian.hinder@aei.mpg.de> | 2013-09-09 11:50:23 +0200 |
---|---|---|
committer | Ian Hinder <ian.hinder@aei.mpg.de> | 2013-09-09 11:50:23 +0200 |
commit | 5db8952a3b94eb25a35b200596189ad2696e874a (patch) | |
tree | 0c3641d709f535c5d5de3a36a4a53388e1be8271 | |
parent | 10e0c6a4513eff6b649ba0f16bbb426384f80888 (diff) |
Thorn.m: Move MoL code generation to new MoL.m
-rw-r--r-- | Tools/CodeGen/CactusBoundary.m | 2 | ||||
-rw-r--r-- | Tools/CodeGen/KrancThorn.m | 2 | ||||
-rw-r--r-- | Tools/CodeGen/MoL.m | 480 | ||||
-rw-r--r-- | Tools/CodeGen/Thorn.m | 453 |
4 files changed, 482 insertions, 455 deletions
diff --git a/Tools/CodeGen/CactusBoundary.m b/Tools/CodeGen/CactusBoundary.m index 610987b..14cbc70 100644 --- a/Tools/CodeGen/CactusBoundary.m +++ b/Tools/CodeGen/CactusBoundary.m @@ -33,7 +33,7 @@ *) BeginPackage["CactusBoundary`", {"CodeGen`", "Thorn`", - "MapLookup`", "KrancGroups`", "Errors`", "Helpers`", "Kranc`"}]; + "MapLookup`", "KrancGroups`", "Errors`", "Helpers`", "Kranc`", "MoL`"}]; GetInheritedImplementations::usage = ""; GetIncludeFiles::usage = ""; diff --git a/Tools/CodeGen/KrancThorn.m b/Tools/CodeGen/KrancThorn.m index 55b9c28..75fa6f2 100644 --- a/Tools/CodeGen/KrancThorn.m +++ b/Tools/CodeGen/KrancThorn.m @@ -30,7 +30,7 @@ BeginPackage["KrancThorn`", {"CodeGen`", "Thorn`", "CalculationFunction`", "Errors`", "Helpers`", "CactusBoundary`", "KrancTensor`", "Param`", "Schedule`", "Interface`", "Kranc`", "Jacobian`", "ConservationCalculation`", "CaKernel`", "Calculation`", "ParamCheck`", - "OpenCL`", "CodeGenConfiguration`", "CodeGenMakefile`", "CodeGenSymmetries`"}]; + "OpenCL`", "CodeGenConfiguration`", "CodeGenMakefile`", "CodeGenSymmetries`", "MoL`"}]; CreateKrancThorn::usage = "Construct a Kranc thorn"; diff --git a/Tools/CodeGen/MoL.m b/Tools/CodeGen/MoL.m new file mode 100644 index 0000000..091bfad --- /dev/null +++ b/Tools/CodeGen/MoL.m @@ -0,0 +1,480 @@ + +(* Copyright 2004-2013 Sascha Husa, Ian Hinder, Christiane Lechner + + This file is part of Kranc. + + Kranc is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kranc is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Kranc; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*) + +BeginPackage[ + "MoL`", + {"Errors`", "Helpers`", "Kranc`", "CodeGenKranc`", "MapLookup`", "CodeGenCactus`", + "CodeGen`", "CodeGenC`", "KrancGroups`"}]; + +CreateMoLRegistrationSource::usage = ""; +CreateMoLBoundariesSource::usage = ""; +CreateMoLExcisionSource::usage = ""; + +Begin["`Private`"]; + +(* ------------------------------------------------------------------------ + MoL Registration + ------------------------------------------------------------------------ *) + +(* MoL registration = {EvolvedGFs -> {h11, ...}, PrimitiveGFs -> {trK, ...}, + BaseImplementation -> "ADMBase", ThornName -> "ADMMoL"} *) + +(* Given a MoL registration structure as defined above, return a + CodeGen structure of a source file which will register the + variables given with MoL. *) +CreateMoLRegistrationSource[spec_, debug_] := + + Module[{tmp, lang}, + + If[debug, + Print["Registering for MoL:"]; + Print[]; + Print[" Evolved Gridfunctions: ", lookup[spec, EvolvedGFs] ]; + Print[" Primitive Gridfunctions: ", lookup[spec, PrimitiveGFs] ]; + ]; + + lang = CodeGenC`SOURCELANGUAGE; + CodeGenC`SOURCELANGUAGE= "C"; + + tmp = {FileHeader["C"], + + Map[IncludeFile, + {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h"}], + + DefineCCTKFunction[lookup[spec,ThornName] <> "_RegisterVars", "void", + {DefineVariable["ierr", "CCTK_INT", "0"], + + CommentedBlock["Register all the evolved grid functions with MoL", + +(* FIXME: We should clarify exactly what should happen with the implementation names here *) + +(* OK. I think that the group name should be passed in qualified, as that is all that we can do. *) + + Map[{"ierr += MoLRegisterEvolved(CCTK_VarIndex(\"", #, "\"), CCTK_VarIndex(\"", + #, "rhs\"));\n"} &, + lookup[spec, EvolvedGFs]]], + + CommentedBlock["Register all the evolved Array functions with MoL", + Map[{"ierr += MoLRegisterEvolved(CCTK_VarIndex(\"", #, "\"), CCTK_VarIndex(\"", + #, "rhs\"));\n"} &, + lookup[spec, EvolvedArrays]]], + + (* Registering all the remaining variables as constrained is + just plain wrong. Read the MoL documentation. It is also not + harmless, I think. *) + + (*CommentedBlock["Register all the primitive grid functions with MoL", + (* We should check ierr *) + Map[{"ierr += MoLRegisterConstrained(CCTK_VarIndex(\"", + #, "\"));\n"} &, + lookup[spec, PrimitiveGFs]]], *) + "return;\n"}]}; + + CodeGenC`SOURCELANGUAGE = lang; + +tmp +]; + +(* ------------------------------------------------------------------------ + MoL Boundaries + ------------------------------------------------------------------------ *) + +(* boundaries spec = {Groups -> {trK, h11, ...}, + BaseImplementation -> "ADMBase", ThornName -> "ADMMoL"} *) + +(* the boundary treatment is split into 3 steps: + 1. excision + 2. symmetries + 3. "other" boundary conditions, e.g. flat, radiative + +To simplify scheduling, testing, etc. the 3 steps are currently applied in separate functions!*) + +(* boundary conditions may have to be applied per GF or goup ; per group +should be more efficient, but sometimes there will be a GF-dependent parameter, +e.g. for radiation BCs *) + +cleanCPP[x_] := Map[StringReplace[FlattenBlock[#], " #" -> "#"]&, x]; + +(* Given a BC registration structure as defined above, return a + CodeGen structure of a source file which does nothing yet! *) +CreateMoLBoundariesSource[spec_] := + + Module[{gfs, groups, unqualifiedGroups, tmp, lang}, + + gfs = lookup[spec, EvolvedGFs]; + groups = lookup[spec, Groups]; + unqualifiedGroups = Map[unqualifiedGroupName, lookup[spec, Groups]]; + + listBCparfileEntry[gforgroup_] := Module[{prefix, unqualName}, + (* include a comment block with template parameter file entries *) + prefix = "#$bound$#" <> lookup[spec, ThornImplementation] <> "::"; + unqualName = unqualifiedGroupName@ToString@gforgroup; + + { + prefix <> unqualName <> "_bound = \"skip\"\n", + prefix <> unqualName <> "_bound_speed = 1.0\n", + prefix <> unqualName <> "_bound_limit = 0.0\n", + prefix <> unqualName <> "_bound_scalar = 0.0\n\n" + }]; + + +(* + symmetryBCGroup[group_] := Module[{boundpar, fullgroupname}, + (* symmetry boundary conditions *) + + fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; + + {"\n", + + " ierr = CartSymGN(cctkGH, \"" <> fullgroupname <> "\");\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Failed to apply symmetry BC for " <> fullgroupname <> "!\");\n"} + ]; +*) + + trivialBCGroup[group_] := Module[{boundpar, fullgroupname}, + (* boundary conditions that do not have parameters besides their name *) + + boundpar = unqualifiedGroupName@group <> "_bound"; + fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; + + {"\n", + "if (CCTK_EQUALS(" <> boundpar <> ", \"none\" ) ||\n", + " CCTK_EQUALS(" <> boundpar <> ", \"static\") ||\n", + " CCTK_EQUALS(" <> boundpar <> ", \"flat\" ) ||\n", + " CCTK_EQUALS(" <> boundpar <> ", \"zero\" ) )\n", + "{\n", + + " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, -1,\n", + " \"" <> fullgroupname <> "\", " <> boundpar <> ");\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Failed to register "<>boundpar<>" BC for "<>fullgroupname<>"!\");\n", + + "}\n"}]; + + + trivialBCGF[gf_] := Module[{boundpar, fullgfname}, + (* boundary conditions that do not have parameters besides their name *) + + boundpar = unqualifiedGroupName@ToString@gf <> "_bound"; + fullgfname = ToString@gf; + + {"\n", + "if (CCTK_EQUALS(" <> boundpar <> ", \"none\" ) ||\n", + " CCTK_EQUALS(" <> boundpar <> ", \"static\") ||\n", + " CCTK_EQUALS(" <> boundpar <> ", \"flat\" ) ||\n", + " CCTK_EQUALS(" <> boundpar <> ", \"zero\" ) )\n", + "{\n", + + " ierr = Boundary_SelectVarForBC(cctkGH, CCTK_ALL_FACES, 1, -1,\n", + " \"" <> fullgfname <> "\", " <> boundpar <> ");\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Failed to register "<>boundpar<>" BC for "<>fullgfname<>"!\");\n", + + "}\n"}]; + + radiationBCGroup[group_] := Module[{boundpar, fullgroupname, myhandle}, + (* a simple radiation boundary condition *) + + boundpar = unqualifiedGroupName@ToString@group <> "_bound"; + fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; + + myhandle = "handle_" <> boundpar; + + {"\n", + "if (CCTK_EQUALS(" <> boundpar <> ", \"radiative\"))\n", + "{\n /* select radiation boundary condition */\n ", + + DefineVariable[myhandle, "static CCTK_INT", "-1"], + + " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", + + " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", + + " if (Util_TableSetReal("<>myhandle<>" , "<> boundpar <>"_limit, \"LIMIT\") < 0)\n", + " CCTK_WARN(0, \"could not set LIMIT value in table!\");\n", + + " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_speed, \"SPEED\") < 0)\n", + " CCTK_WARN(0, \"could not set SPEED value in table!\");\n", + + "\n", + " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", + " \"" <> fullgroupname <> "\", \"Radiation\");\n\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Failed to register Radiation BC for "<>fullgroupname<>"!\");\n", + + "\n}\n"}]; + + + radiationBCGF[gf_] := Module[{boundpar, fullgfname, myhandle}, + (* a simple radiation boundary condition *) + + boundpar = unqualifiedGroupName@ToString@gf <> "_bound"; + fullgfname = ToString@gf; + + myhandle = "handle_" <> boundpar; + + {"\n", + "if (CCTK_EQUALS(" <> boundpar <> ", \"radiative\"))\n", + "{\n /* select radiation boundary condition */\n ", + + DefineVariable[myhandle, "static CCTK_INT", "-1"], + + " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", + + " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", + + " if (Util_TableSetReal("<>myhandle<>" , "<> boundpar <>"_limit, \"LIMIT\") < 0)\n", + " CCTK_WARN(0, \"could not set LIMIT value in table!\");\n", + + " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_speed, \"SPEED\") < 0)\n", + " CCTK_WARN(0, \"could not set SPEED value in table!\");\n", + + "\n", + " ierr = Boundary_SelectVarForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", + " \"" <> fullgfname <> "\", \"Radiation\");\n\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Failed to register Radiation BC for "<>fullgfname<>"!\");\n", + + "\n}\n"}]; + + scalarBCGroup[group_] := Module[{boundpar, fullgroupname, myhandle}, + (* simple dirichlet boundary condition *) + + boundpar = unqualifiedGroupName@group <> "_bound"; + fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; + myhandle = "handle_" <> boundpar; + + {"\n", + "if (CCTK_EQUALS(" <> boundpar <> ", \"scalar\"))\n", + "{\n /* select scalar boundary condition */\n ", + + DefineVariable[myhandle, "static CCTK_INT", "-1"], + + " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", + + " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", + + " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_scalar, \"SCALAR\") < 0)\n", + " CCTK_WARN(0, \"could not set SCALAR value in table!\");\n", + + "\n", + " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", + " \"" <> fullgroupname <> "\", \"scalar\");\n\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Failed to register Scalar BC for "<>fullgroupname<>"!\");\n", + + "\n}\n"}]; + + + scalarBCGF[gf_] := Module[{boundpar, fullgfname, myhandle}, + (* simple dirichlet boundary condition *) + + boundpar = unqualifiedGroupName@ToString@gf <> "_bound"; + fullgfname = ToString@gf; + myhandle = "handle_" <> boundpar; + + {"\n", + "if (CCTK_EQUALS(" <> boundpar <> ", \"scalar\"))\n", + "{\n /* select scalar boundary condition */\n ", + + DefineVariable[myhandle, "static CCTK_INT", "-1"], + + " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", + + " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", + + " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_scalar, \"SCALAR\") < 0)\n", + " CCTK_WARN(0, \"could not set SCALAR value in table!\");\n", + + "\n", + " ierr = Boundary_SelectVarForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", + " \"" <> fullgfname <> "\", \"scalar\");\n\n", + + " if (ierr < 0)\n", + " CCTK_WARN(0, \"Error in registering Scalar BC for "<>fullgfname<>"!\");\n", + + "\n}\n"}]; + + + lang = CodeGenC`SOURCELANGUAGE; + CodeGenC`SOURCELANGUAGE = "C"; + + tmp = {FileHeader["C"], + + + Map[IncludeFile, + {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h", + "cctk_Faces.h", "util_Table.h", "Symmetry.h"}], + + {"\n\n", + "/* the boundary treatment is split into 3 steps: */\n", + "/* 1. excision */\n", + "/* 2. symmetries */\n", + "/* 3. \"other\" boundary conditions, e.g. radiative */\n\n", + "/* to simplify scheduling and testing, the 3 steps */\n", + "/* are currently applied in separate functions */\n\n"}, + + + cleanCPP@DefineCCTKFunction[lookup[spec,ThornName] <> "_CheckBoundaries", + "void", + {"return;\n"}], + + + cleanCPP@DefineCCTKFunction[lookup[spec,ThornName] <> "_SelectBoundConds", + "void", + {DefineVariable["ierr", "CCTK_INT", "0"], + +(* + Map[symmetryBCGroup, groups], +*) + + Map[trivialBCGroup, groups], + Map[trivialBCGF, gfs], + + Map[radiationBCGroup, groups], + Map[radiationBCGF, gfs], + + Map[scalarBCGroup, groups], + Map[scalarBCGF, gfs], + + "return;\n" + }], + + "\n\n\n", + "/* template for entries in parameter file:\n", + Map[listBCparfileEntry, unqualifiedGroups], + Map[listBCparfileEntry, gfs], + "*/\n\n" + }; + + CodeGenC`SOURCELANGUAGE = lang; +tmp +]; + +CreateMoLExcisionSource[spec_] := + + Module[{gfs, currentlang, body, excisionExtrap}, + + gfs = lookup[spec, ExcisionGFs]; + + Print["Applying excision to GFs: ", gfs]; + + currentlang = CodeGenC`SOURCELANGUAGE; + CodeGenC`SOURCELANGUAGE = "Fortran"; + + excisionExtrap[gf_] := " call ExcisionExtrapolate(ierr, " + <> ToString@gf <> ", " <> ToString@gf + <> "_p, emask, exnormx, exnormy, exnormz, nx, ny, nz, "<> ToString@gf <> "_bound_limit)\n"; + + body = {FileHeader["Fortran"], + + Map[IncludeFile, + {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h"}], + + {"\n\n", + "! the boundary treatment is split into 3 steps: \n", + "! 1. excision \n", + "! 2. symmetries \n", + "! 3. \"other\" boundary conditions, e.g. radiative \n", + "! to simplify scheduling and testing, the 3 steps \n", + "! are currently applied in separate functions \n\n"}, + + cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_FindBoundary", + {"! APPLY EXCISION\n\n", + DefineVariable["ierr", "CCTK_INT :: ", "0"], + "", + + "integer :: nx, ny, nz\n\n", + + "! grid parameters\n", + + "nx = cctk_lsh(1)\n", + "ny = cctk_lsh(2)\n", + "nz = cctk_lsh(3)\n\n", + + "if ( (excision .ne. 0).AND.(find_excision_boundary .ne. 0) ) then\n\n", + + " call ExcisionFindBoundary(ierr, emask, nx, ny, nz)\n", + " if (ierr < 0) call CCTK_WARN(2, \"findboundary exited with an error\")\n\n", + + "endif\n\n", + "return\n"}], + + cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_FindNormals", + {"! APPLY EXCISION\n\n", + DefineVariable["ierr", "CCTK_INT :: ", "0"], + "", + + "integer :: nx, ny, nz\n\n", + + "! grid parameters\n", + + "nx = cctk_lsh(1)\n", + "ny = cctk_lsh(2)\n", + "nz = cctk_lsh(3)\n\n", + + "if ( (excision .ne. 0).AND.(find_excision_normals .ne. 0) ) then\n\n", + + " call ExcisionFindNormals(ierr, emask, exnormx, exnormy, exnormz, nx, ny, nz)\n", + " if (ierr < 0) call CCTK_WARN(2, \"findnormals exited with an error\")\n\n", + + "endif\n\n", + "return\n"}], + + + cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_ApplyExcision", + {"! APPLY EXCISION\n\n", + DefineVariable["ierr", "CCTK_INT :: ", "0"], + "", + + "integer :: nx, ny, nz\n\n", + + "! grid parameters\n", + + "nx = cctk_lsh(1)\n", + "ny = cctk_lsh(2)\n", + "nz = cctk_lsh(3)\n\n", + + "if (excision .ne. 0) then\n", + + " call CCTK_INFO(\"Applying LegoExcision\")\n\n", + + Map[excisionExtrap, gfs], + "endif\n\n", + "return\n"}] +}; + +CodeGenC`SOURCELANGUAGE = currentlang; + +body +]; + + + +End[]; + +EndPackage[]; diff --git a/Tools/CodeGen/Thorn.m b/Tools/CodeGen/Thorn.m index c45883f..95c296d 100644 --- a/Tools/CodeGen/Thorn.m +++ b/Tools/CodeGen/Thorn.m @@ -31,9 +31,6 @@ BeginPackage["Thorn`", "CodeGen`", "CodeGenC`", "CodeGenCactus`", "CodeGenKranc` interface to this package. *) CreateThorn::usage = "Create a general Cactus thorn from a thorn specification structure"; -CreateMoLRegistrationSource::usage = ""; -CreateMoLBoundariesSource::usage = ""; -CreateMoLExcisionSource::usage = ""; CreateSetterSource::usage = ""; CreateMPCharSource::usage = ""; CreatePrecompMacros::usage = ""; @@ -114,456 +111,6 @@ CreateSetterSource[calcs_, debug_, include_, CreateCalculationFunction[calc, opts]}]; - - - - -(* ------------------------------------------------------------------------ - MoL Registration - ------------------------------------------------------------------------ *) - -(* MoL registration = {EvolvedGFs -> {h11, ...}, PrimitiveGFs -> {trK, ...}, - BaseImplementation -> "ADMBase", ThornName -> "ADMMoL"} *) - -(* Given a MoL registration structure as defined above, return a - CodeGen structure of a source file which will register the - variables given with MoL. *) -CreateMoLRegistrationSource[spec_, debug_] := - - Module[{tmp, lang}, - - If[debug, - Print["Registering for MoL:"]; - Print[]; - Print[" Evolved Gridfunctions: ", lookup[spec, EvolvedGFs] ]; - Print[" Primitive Gridfunctions: ", lookup[spec, PrimitiveGFs] ]; - ]; - - lang = CodeGenC`SOURCELANGUAGE; - CodeGenC`SOURCELANGUAGE= "C"; - - tmp = {FileHeader["C"], - - Map[IncludeFile, - {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h"}], - - DefineCCTKFunction[lookup[spec,ThornName] <> "_RegisterVars", "void", - {DefineVariable["ierr", "CCTK_INT", "0"], - - CommentedBlock["Register all the evolved grid functions with MoL", - -(* FIXME: We should clarify exactly what should happen with the implementation names here *) - -(* OK. I think that the group name should be passed in qualified, as that is all that we can do. *) - - Map[{"ierr += MoLRegisterEvolved(CCTK_VarIndex(\"", #, "\"), CCTK_VarIndex(\"", - #, "rhs\"));\n"} &, - lookup[spec, EvolvedGFs]]], - - CommentedBlock["Register all the evolved Array functions with MoL", - Map[{"ierr += MoLRegisterEvolved(CCTK_VarIndex(\"", #, "\"), CCTK_VarIndex(\"", - #, "rhs\"));\n"} &, - lookup[spec, EvolvedArrays]]], - - (* Registering all the remaining variables as constrained is - just plain wrong. Read the MoL documentation. It is also not - harmless, I think. *) - - (*CommentedBlock["Register all the primitive grid functions with MoL", - (* We should check ierr *) - Map[{"ierr += MoLRegisterConstrained(CCTK_VarIndex(\"", - #, "\"));\n"} &, - lookup[spec, PrimitiveGFs]]], *) - "return;\n"}]}; - - CodeGenC`SOURCELANGUAGE = lang; - -tmp -]; - -(* ------------------------------------------------------------------------ - MoL Boundaries - ------------------------------------------------------------------------ *) - -(* boundaries spec = {Groups -> {trK, h11, ...}, - BaseImplementation -> "ADMBase", ThornName -> "ADMMoL"} *) - -(* the boundary treatment is split into 3 steps: - 1. excision - 2. symmetries - 3. "other" boundary conditions, e.g. flat, radiative - -To simplify scheduling, testing, etc. the 3 steps are currently applied in separate functions!*) - -(* boundary conditions may have to be applied per GF or goup ; per group -should be more efficient, but sometimes there will be a GF-dependent parameter, -e.g. for radiation BCs *) - -cleanCPP[x_] := Map[StringReplace[FlattenBlock[#], " #" -> "#"]&, x]; - -(* Given a BC registration structure as defined above, return a - CodeGen structure of a source file which does nothing yet! *) -CreateMoLBoundariesSource[spec_] := - - Module[{gfs, groups, unqualifiedGroups, tmp, lang}, - - gfs = lookup[spec, EvolvedGFs]; - groups = lookup[spec, Groups]; - unqualifiedGroups = Map[unqualifiedGroupName, lookup[spec, Groups]]; - - listBCparfileEntry[gforgroup_] := Module[{prefix, unqualName}, - (* include a comment block with template parameter file entries *) - prefix = "#$bound$#" <> lookup[spec, ThornImplementation] <> "::"; - unqualName = unqualifiedGroupName@ToString@gforgroup; - - { - prefix <> unqualName <> "_bound = \"skip\"\n", - prefix <> unqualName <> "_bound_speed = 1.0\n", - prefix <> unqualName <> "_bound_limit = 0.0\n", - prefix <> unqualName <> "_bound_scalar = 0.0\n\n" - }]; - - -(* - symmetryBCGroup[group_] := Module[{boundpar, fullgroupname}, - (* symmetry boundary conditions *) - - fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; - - {"\n", - - " ierr = CartSymGN(cctkGH, \"" <> fullgroupname <> "\");\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Failed to apply symmetry BC for " <> fullgroupname <> "!\");\n"} - ]; -*) - - trivialBCGroup[group_] := Module[{boundpar, fullgroupname}, - (* boundary conditions that do not have parameters besides their name *) - - boundpar = unqualifiedGroupName@group <> "_bound"; - fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; - - {"\n", - "if (CCTK_EQUALS(" <> boundpar <> ", \"none\" ) ||\n", - " CCTK_EQUALS(" <> boundpar <> ", \"static\") ||\n", - " CCTK_EQUALS(" <> boundpar <> ", \"flat\" ) ||\n", - " CCTK_EQUALS(" <> boundpar <> ", \"zero\" ) )\n", - "{\n", - - " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, -1,\n", - " \"" <> fullgroupname <> "\", " <> boundpar <> ");\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Failed to register "<>boundpar<>" BC for "<>fullgroupname<>"!\");\n", - - "}\n"}]; - - - trivialBCGF[gf_] := Module[{boundpar, fullgfname}, - (* boundary conditions that do not have parameters besides their name *) - - boundpar = unqualifiedGroupName@ToString@gf <> "_bound"; - fullgfname = ToString@gf; - - {"\n", - "if (CCTK_EQUALS(" <> boundpar <> ", \"none\" ) ||\n", - " CCTK_EQUALS(" <> boundpar <> ", \"static\") ||\n", - " CCTK_EQUALS(" <> boundpar <> ", \"flat\" ) ||\n", - " CCTK_EQUALS(" <> boundpar <> ", \"zero\" ) )\n", - "{\n", - - " ierr = Boundary_SelectVarForBC(cctkGH, CCTK_ALL_FACES, 1, -1,\n", - " \"" <> fullgfname <> "\", " <> boundpar <> ");\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Failed to register "<>boundpar<>" BC for "<>fullgfname<>"!\");\n", - - "}\n"}]; - - radiationBCGroup[group_] := Module[{boundpar, fullgroupname, myhandle}, - (* a simple radiation boundary condition *) - - boundpar = unqualifiedGroupName@ToString@group <> "_bound"; - fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; - - myhandle = "handle_" <> boundpar; - - {"\n", - "if (CCTK_EQUALS(" <> boundpar <> ", \"radiative\"))\n", - "{\n /* select radiation boundary condition */\n ", - - DefineVariable[myhandle, "static CCTK_INT", "-1"], - - " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", - - " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", - - " if (Util_TableSetReal("<>myhandle<>" , "<> boundpar <>"_limit, \"LIMIT\") < 0)\n", - " CCTK_WARN(0, \"could not set LIMIT value in table!\");\n", - - " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_speed, \"SPEED\") < 0)\n", - " CCTK_WARN(0, \"could not set SPEED value in table!\");\n", - - "\n", - " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", - " \"" <> fullgroupname <> "\", \"Radiation\");\n\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Failed to register Radiation BC for "<>fullgroupname<>"!\");\n", - - "\n}\n"}]; - - - radiationBCGF[gf_] := Module[{boundpar, fullgfname, myhandle}, - (* a simple radiation boundary condition *) - - boundpar = unqualifiedGroupName@ToString@gf <> "_bound"; - fullgfname = ToString@gf; - - myhandle = "handle_" <> boundpar; - - {"\n", - "if (CCTK_EQUALS(" <> boundpar <> ", \"radiative\"))\n", - "{\n /* select radiation boundary condition */\n ", - - DefineVariable[myhandle, "static CCTK_INT", "-1"], - - " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", - - " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", - - " if (Util_TableSetReal("<>myhandle<>" , "<> boundpar <>"_limit, \"LIMIT\") < 0)\n", - " CCTK_WARN(0, \"could not set LIMIT value in table!\");\n", - - " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_speed, \"SPEED\") < 0)\n", - " CCTK_WARN(0, \"could not set SPEED value in table!\");\n", - - "\n", - " ierr = Boundary_SelectVarForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", - " \"" <> fullgfname <> "\", \"Radiation\");\n\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Failed to register Radiation BC for "<>fullgfname<>"!\");\n", - - "\n}\n"}]; - - scalarBCGroup[group_] := Module[{boundpar, fullgroupname, myhandle}, - (* simple dirichlet boundary condition *) - - boundpar = unqualifiedGroupName@group <> "_bound"; - fullgroupname = qualifyGroupName[ToString@group, lookup[spec, BaseImplementation]]; - myhandle = "handle_" <> boundpar; - - {"\n", - "if (CCTK_EQUALS(" <> boundpar <> ", \"scalar\"))\n", - "{\n /* select scalar boundary condition */\n ", - - DefineVariable[myhandle, "static CCTK_INT", "-1"], - - " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", - - " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", - - " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_scalar, \"SCALAR\") < 0)\n", - " CCTK_WARN(0, \"could not set SCALAR value in table!\");\n", - - "\n", - " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", - " \"" <> fullgroupname <> "\", \"scalar\");\n\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Failed to register Scalar BC for "<>fullgroupname<>"!\");\n", - - "\n}\n"}]; - - - scalarBCGF[gf_] := Module[{boundpar, fullgfname, myhandle}, - (* simple dirichlet boundary condition *) - - boundpar = unqualifiedGroupName@ToString@gf <> "_bound"; - fullgfname = ToString@gf; - myhandle = "handle_" <> boundpar; - - {"\n", - "if (CCTK_EQUALS(" <> boundpar <> ", \"scalar\"))\n", - "{\n /* select scalar boundary condition */\n ", - - DefineVariable[myhandle, "static CCTK_INT", "-1"], - - " if ("<>myhandle<>" < 0) "<>myhandle<>" = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);\n", - - " if ("<>myhandle<>" < 0) CCTK_WARN(0, \"could not create table!\");\n", - - " if (Util_TableSetReal("<>myhandle<>" ," <> boundpar <> "_scalar, \"SCALAR\") < 0)\n", - " CCTK_WARN(0, \"could not set SCALAR value in table!\");\n", - - "\n", - " ierr = Boundary_SelectVarForBC(cctkGH, CCTK_ALL_FACES, 1, "<>myhandle<>", \n", - " \"" <> fullgfname <> "\", \"scalar\");\n\n", - - " if (ierr < 0)\n", - " CCTK_WARN(0, \"Error in registering Scalar BC for "<>fullgfname<>"!\");\n", - - "\n}\n"}]; - - - lang = CodeGenC`SOURCELANGUAGE; - CodeGenC`SOURCELANGUAGE = "C"; - - tmp = {FileHeader["C"], - - - Map[IncludeFile, - {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h", - "cctk_Faces.h", "util_Table.h", "Symmetry.h"}], - - {"\n\n", - "/* the boundary treatment is split into 3 steps: */\n", - "/* 1. excision */\n", - "/* 2. symmetries */\n", - "/* 3. \"other\" boundary conditions, e.g. radiative */\n\n", - "/* to simplify scheduling and testing, the 3 steps */\n", - "/* are currently applied in separate functions */\n\n"}, - - - cleanCPP@DefineCCTKFunction[lookup[spec,ThornName] <> "_CheckBoundaries", - "void", - {"return;\n"}], - - - cleanCPP@DefineCCTKFunction[lookup[spec,ThornName] <> "_SelectBoundConds", - "void", - {DefineVariable["ierr", "CCTK_INT", "0"], - -(* - Map[symmetryBCGroup, groups], -*) - - Map[trivialBCGroup, groups], - Map[trivialBCGF, gfs], - - Map[radiationBCGroup, groups], - Map[radiationBCGF, gfs], - - Map[scalarBCGroup, groups], - Map[scalarBCGF, gfs], - - "return;\n" - }], - - "\n\n\n", - "/* template for entries in parameter file:\n", - Map[listBCparfileEntry, unqualifiedGroups], - Map[listBCparfileEntry, gfs], - "*/\n\n" - }; - - CodeGenC`SOURCELANGUAGE = lang; -tmp -]; - -CreateMoLExcisionSource[spec_] := - - Module[{gfs, currentlang, body, excisionExtrap}, - - gfs = lookup[spec, ExcisionGFs]; - - Print["Applying excision to GFs: ", gfs]; - - currentlang = CodeGenC`SOURCELANGUAGE; - CodeGenC`SOURCELANGUAGE = "Fortran"; - - excisionExtrap[gf_] := " call ExcisionExtrapolate(ierr, " - <> ToString@gf <> ", " <> ToString@gf - <> "_p, emask, exnormx, exnormy, exnormz, nx, ny, nz, "<> ToString@gf <> "_bound_limit)\n"; - - body = {FileHeader["Fortran"], - - Map[IncludeFile, - {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h"}], - - {"\n\n", - "! the boundary treatment is split into 3 steps: \n", - "! 1. excision \n", - "! 2. symmetries \n", - "! 3. \"other\" boundary conditions, e.g. radiative \n", - "! to simplify scheduling and testing, the 3 steps \n", - "! are currently applied in separate functions \n\n"}, - - cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_FindBoundary", - {"! APPLY EXCISION\n\n", - DefineVariable["ierr", "CCTK_INT :: ", "0"], - "", - - "integer :: nx, ny, nz\n\n", - - "! grid parameters\n", - - "nx = cctk_lsh(1)\n", - "ny = cctk_lsh(2)\n", - "nz = cctk_lsh(3)\n\n", - - "if ( (excision .ne. 0).AND.(find_excision_boundary .ne. 0) ) then\n\n", - - " call ExcisionFindBoundary(ierr, emask, nx, ny, nz)\n", - " if (ierr < 0) call CCTK_WARN(2, \"findboundary exited with an error\")\n\n", - - "endif\n\n", - "return\n"}], - - cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_FindNormals", - {"! APPLY EXCISION\n\n", - DefineVariable["ierr", "CCTK_INT :: ", "0"], - "", - - "integer :: nx, ny, nz\n\n", - - "! grid parameters\n", - - "nx = cctk_lsh(1)\n", - "ny = cctk_lsh(2)\n", - "nz = cctk_lsh(3)\n\n", - - "if ( (excision .ne. 0).AND.(find_excision_normals .ne. 0) ) then\n\n", - - " call ExcisionFindNormals(ierr, emask, exnormx, exnormy, exnormz, nx, ny, nz)\n", - " if (ierr < 0) call CCTK_WARN(2, \"findnormals exited with an error\")\n\n", - - "endif\n\n", - "return\n"}], - - - cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_ApplyExcision", - {"! APPLY EXCISION\n\n", - DefineVariable["ierr", "CCTK_INT :: ", "0"], - "", - - "integer :: nx, ny, nz\n\n", - - "! grid parameters\n", - - "nx = cctk_lsh(1)\n", - "ny = cctk_lsh(2)\n", - "nz = cctk_lsh(3)\n\n", - - "if (excision .ne. 0) then\n", - - " call CCTK_INFO(\"Applying LegoExcision\")\n\n", - - Map[excisionExtrap, gfs], - "endif\n\n", - "return\n"}] -}; - -CodeGenC`SOURCELANGUAGE = currentlang; - -body -]; - - - (* ------------------------------------------------------------------------ *) (* set Characteristic Info for MultiPatch *) (* ------------------------------------------------------------------------ *) |