diff options
author | shusa <shusa> | 2004-05-09 19:34:21 +0000 |
---|---|---|
committer | shusa <shusa> | 2004-05-09 19:34:21 +0000 |
commit | 7c05ab152724573b390868b99d4d3eef00e147da (patch) | |
tree | 418b79742833ccd22b4e90bf0b98ba7c9ac83f4d /Tools/CodeGen/Thorn.m | |
parent | d62d08ade47fd11fa8999c2d66b8f506462503f8 (diff) |
Initial revision
SKIPPED:
Examples/ADM/ADMEqs.m
Examples/ADM/ADMTT.m
Examples/ADM/BuildADMTT
Examples/ADM/KrancADMRicciMetric100.par
Examples/ADM/KrancADMRicciStandard100.par
Examples/ADM/KrancADMTT.m
Examples/ADM/Makefile
Examples/ADM/README
Examples/ADM/ThornGenADM_front.nb
Examples/ADM/ThornGen_ADM.m
Examples/ADM/ThornGen_ADM2.m
Examples/ADM/arrangement_KrancADM.tar.gz
Examples/ADM/data_adm.tar.gz
Examples/BSSN/BSSNTT.m
Examples/BSSN/BuildBSSNTT
Examples/BSSN/Makefile
Examples/BSSN/freeBSSN/freeBSSN.th
Examples/BSSN/freeBSSN/BSSNMoL/interface.ccl
Examples/BSSN/freeBSSN/BSSNMoL/param.ccl
Examples/BSSN/freeBSSN/BSSNMoL/schedule.ccl
Examples/BSSN/freeBSSN/BSSNMoL/src/BSSNMoL_ApplyExcision.F90
Examples/BSSN/freeBSSN/BSSNMoL/src/BSSNMoL_Boundaries.c
Examples/BSSN/freeBSSN/BSSNMoL/src/BSSNMoL_CalcRHS.c
Examples/BSSN/freeBSSN/BSSNMoL/src/BSSNMoL_RegisterVars.c
Examples/BSSN/freeBSSN/BSSNMoL/src/Startup.c
Examples/BSSN/freeBSSN/BSSNMoL/src/make.code.defn
Examples/BSSN/freeBSSN/BSSNMoL/src/precomputations.h
Examples/BSSN/freeBSSN/BSSNTranslator/interface.ccl
Examples/BSSN/freeBSSN/BSSNTranslator/param.ccl
Examples/BSSN/freeBSSN/BSSNTranslator/schedule.ccl
Examples/BSSN/freeBSSN/BSSNTranslator/src/BSSNTranslator_Setter.c
Examples/BSSN/freeBSSN/BSSNTranslator/src/Startup.c
Examples/BSSN/freeBSSN/BSSNTranslator/src/make.code.defn
Examples/BSSN/freeBSSN/BSSNTranslator/src/precomputations.h
Examples/BSSN/freeBSSN/OLDpar/BSSN2GaugeWaveR0.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2GaugeWaveR1.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2GaugeWaveR2.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2PolarizedGowdyCollapseR0.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2PolarizedGowdyCollapseR1.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2PolarizedGowdyCollapseR2.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2PolarizedGowdyExpandR0.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2PolarizedGowdyExpandR1.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2PolarizedGowdyExpandR2.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2RobustR0.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2RobustR1.par
Examples/BSSN/freeBSSN/OLDpar/BSSN2RobustR2.par
Examples/BSSN/freeBSSN/evalBSSNConstraints/interface.ccl
Examples/BSSN/freeBSSN/evalBSSNConstraints/param.ccl
Examples/BSSN/freeBSSN/evalBSSNConstraints/schedule.ccl
Examples/BSSN/freeBSSN/evalBSSNConstraints/src/Startup.c
Examples/BSSN/freeBSSN/evalBSSNConstraints/src/evalBSSNConstraints_Eval.c
Examples/BSSN/freeBSSN/evalBSSNConstraints/src/make.code.defn
Examples/BSSN/freeBSSN/evalBSSNConstraints/src/precomputations.h
Examples/BSSN/freeBSSN/freeBSSNBase/interface.ccl
Examples/BSSN/freeBSSN/freeBSSNBase/param.ccl
Examples/BSSN/freeBSSN/freeBSSNBase/schedule.ccl
Examples/BSSN/freeBSSN/freeBSSNBase/src/RegisterSymmetries.c
Examples/BSSN/freeBSSN/freeBSSNBase/src/Startup.c
Examples/BSSN/freeBSSN/freeBSSNBase/src/make.code.defn
Examples/BSSN/freeBSSN/harmonicLapseMoL/interface.ccl
Examples/BSSN/freeBSSN/harmonicLapseMoL/param.ccl
Examples/BSSN/freeBSSN/harmonicLapseMoL/schedule.ccl
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/Startup.c
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/harmonicLapseMoL_ApplyExcision.F90
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/harmonicLapseMoL_Boundaries.c
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/harmonicLapseMoL_CalcRHS.c
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/harmonicLapseMoL_RegisterVars.c
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/make.code.defn
Examples/BSSN/freeBSSN/harmonicLapseMoL/src/precomputations.h
Examples/BSSN/freeBSSN/par/BSSN2GaugeWaveR0.par
Examples/BSSN/freeBSSN/par/BSSN2GaugeWaveR1.par
Examples/BSSN/freeBSSN/par/BSSN2GaugeWaveR2.par
Examples/BSSN/freeBSSN/par/BSSN2PolarizedGowdyCollapseR0.par
Examples/BSSN/freeBSSN/par/BSSN2PolarizedGowdyCollapseR1.par
Examples/BSSN/freeBSSN/par/BSSN2PolarizedGowdyCollapseR2.par
Examples/BSSN/freeBSSN/par/BSSN2PolarizedGowdyExpandR0.par
Examples/BSSN/freeBSSN/par/BSSN2PolarizedGowdyExpandR1.par
Examples/BSSN/freeBSSN/par/BSSN2PolarizedGowdyExpandR2.par
Examples/BSSN/freeBSSN/par/BSSN2RobustR0.par
Examples/BSSN/freeBSSN/par/BSSN2RobustR1.par
Examples/BSSN/freeBSSN/par/BSSN2RobustR2.par
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/interface.ccl
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/param.ccl
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/schedule.ccl
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/src/Startup.c
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/src/make.code.defn
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/src/precomputations.h
Examples/BSSN/freeBSSN/projectAlgebraicConstraints/src/projectAlgebraicConstraints_Set.c
Examples/BSSN/freeBSSN/setHarmonicLapse/interface.ccl
Examples/BSSN/freeBSSN/setHarmonicLapse/param.ccl
Examples/BSSN/freeBSSN/setHarmonicLapse/schedule.ccl
Examples/BSSN/freeBSSN/setHarmonicLapse/src/Startup.c
Examples/BSSN/freeBSSN/setHarmonicLapse/src/make.code.defn
Examples/BSSN/freeBSSN/setHarmonicLapse/src/precomputations.h
Examples/BSSN/freeBSSN/setHarmonicLapse/src/setHarmonicLapse_Set.c
Examples/BSSN/freeBSSN/setUnitLapse/interface.ccl
Examples/BSSN/freeBSSN/setUnitLapse/param.ccl
Examples/BSSN/freeBSSN/setUnitLapse/schedule.ccl
Examples/BSSN/freeBSSN/setUnitLapse/src/Startup.c
Examples/BSSN/freeBSSN/setUnitLapse/src/make.code.defn
Examples/BSSN/freeBSSN/setUnitLapse/src/precomputations.h
Examples/BSSN/freeBSSN/setUnitLapse/src/setUnitLapse_Set.c
Examples/BSSN/freeBSSN/setZeroShift/interface.ccl
Examples/BSSN/freeBSSN/setZeroShift/param.ccl
Examples/BSSN/freeBSSN/setZeroShift/schedule.ccl
Examples/BSSN/freeBSSN/setZeroShift/src/Startup.c
Examples/BSSN/freeBSSN/setZeroShift/src/make.code.defn
Examples/BSSN/freeBSSN/setZeroShift/src/precomputations.h
Examples/BSSN/freeBSSN/setZeroShift/src/setZeroShift_Set.c
Examples/KleinGordon/Components.nb
Examples/KleinGordon/KGTT.m
Examples/KleinGordon/ListOfEqsLhsRhsComp.m
Examples/KleinGordon/MKG100.par
Examples/KleinGordon/MKGTT.m
Examples/KleinGordon/README
Examples/KleinGordon/ThornGen_front.nb
Examples/KleinGordon/arrangement_MKG.tar.gz
Examples/KleinGordon/data_mkg.tar.gz
Examples/Maxwell/3+1_Decomp_Maxwell.nb
Examples/Maxwell/EM100.par
Examples/Maxwell/EMTT.m
Examples/Maxwell/Initializations_Maxwell.nb
Examples/Maxwell/ListOfConstrComp.m
Examples/Maxwell/ListOfEqsLhsRhsComp.m
Examples/Maxwell/Maxwell_Demo.nb
Examples/Maxwell/README
Examples/Maxwell/README_internal
Examples/Maxwell/ThornGen_front.nb
Examples/Maxwell/Using_Tools_Constr.nb
Examples/Maxwell/arrangement_EM.tar.gz
Examples/Maxwell/data_em.tar.gz
Tools/TensorFactory/ComponentsTools.nb
Tools/TensorFactory/DecomposeTools.nb
Tools/TensorFactory/FrameDecomposeTools.nb
Tools/TensorFactory/GaussCodazzi.nb
Tools/TensorFactory/Ricci.tex
Tools/TensorFactory/StartMathTensor.m
Tools/TensorFactory/TeXTools.nb
Tools/TensorFactory/Doc/Characteristics.nb
Tools/TensorFactory/Doc/DocGaussCodazzi.nb
Tools/TensorFactory/Doc/Om1EvolEqs.m
Tools/TensorFactory/Doc/exampleTeX.nb
Tools/TensorFactory/Doc/Papers/ERE2003.pdf
Tools/TensorFactory/Doc/Talks/compalg.pdf
Diffstat (limited to 'Tools/CodeGen/Thorn.m')
-rw-r--r-- | Tools/CodeGen/Thorn.m | 791 |
1 files changed, 791 insertions, 0 deletions
diff --git a/Tools/CodeGen/Thorn.m b/Tools/CodeGen/Thorn.m new file mode 100644 index 0000000..3224228 --- /dev/null +++ b/Tools/CodeGen/Thorn.m @@ -0,0 +1,791 @@ + +(* $Id$ *) + +(* Copyright 2004 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 Foobar; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*) + +(* This package provides a set of functions to create the various + parts of a Cactus thorn and assemble them. *) + +BeginPackage["sym`"]; + +(* These symbols are used in this file. Whenever this package is + used, the symbols will be added into the sym` context. You will + need to make sure the sym` context is on your ContextPath to use + the symbols without the sym` prefix. *) + +{AccumulatorBase, Name, Type, Extend, Default, Comment, Range, Implementation, Group, +SchedulePoint, Language, SynchronizedGroups, StorageGroups, +Timelevels, VariableType, GridType, Visibility, Variables, +Implementations, Value, AllowedValues, UsedParameters, Description, +ExtendedParameters, NewParameters, Directory, Interface, Param, +Schedule, Sources, Makefile, Filename, Contents, ThornName, +BaseImplementation, EvolvedGFs, PrimitiveGFs, Groups, Calculation, +GridFunctions, Shorthands, Equations, Parameter, Value, UsesFunctions, +ArgString, Conditional, D1, D2, D3, D11, D22, D33, D21, D31, D32, +Textual, TriggerGroups}; + +{ExcisionGFs}; + +EndPackage[]; + +BeginPackage["Thorn`", "CodeGen`", "CalculationFunction`", "MapLookup`"]; + +(* These functions are externally visible, and comprise the public + interface to this package. *) +CreateSchedule::usage = "Create the content of the schedule.ccl file."; +CreateMakefile::usage = "Create the content of the Cactus make.code.defn file."; +CreateInterface::usage = "Create the content of the interface.ccl file."; +CreateParam::usage = "Create the content of the param.ccl file."; +Quote::usage = ""; (* This should not be in this package *) +CreateThorn::usage = "Create a general Cactus thorn from +a thorn specification structure"; +CreateSymmetriesRegistrationSource::usage = ""; +CreateMoLRegistrationSource::usage = ""; +CreateMoLBoundariesSource::usage = ""; +CreateMoLExcisionSource::usage = ""; +CreateSetterSource::usage = ""; +CreatePrecompMacros::usage = ""; +CreateStartupFile::usage = ""; + +(* Ensure that we can refer to symbols without the `sym prefix *) +$ContextPath = Join[{"sym`"}, $ContextPath]; + +Begin["`Private`"]; + + +(* ------------------------------------------------------------------------ + Miscellaneous definitions, could be moved elsewhere + ------------------------------------------------------------------------ *) + +(* Create a directory if it does not exist already *) +ensureDirectory[name_] := + If[FileType[name] == None, + CreateDirectory[name]]; + + +(* date, user, etc. *) +date[] := ToString[Date[][[3]]] <> "/" <> + ToString[Date[][[2]]] <> "/" <> + ToString[Date[][[1]]] + + +dateLong[] := ToString[Date[][[3]]] <> "/" <> + ToString[Date[][[2]]] <> "/" <> + ToString[Date[][[1]]] <> "/" <> " " <> + ToString[Date[][[4]]] <> ":" <> + ToString[Date[][[5]]] <> ":" <> + ToString[Date[][[6]]]; + + +user[] := ToString[<< "!whoami"]; + + +whoWhen[lang_] := Module[{com1, com2}, + +com1 = "UNRECOGNIZED LANGUAGE"; +com2 = "UNRECOGNIZED LANGUAGE"; + +If[(lang == "C" || lang == "c"), + com1 = "/* "; com2 = " */"; +]; + +If[(lang == "Fortran" || lang == "FORTRAN" || lang == "F90" || lang == "F95"), + com1 = "!"; com2 = ""; +]; + +If[(lang == "F77"), + com1 = "C"; com2 = ""; +]; + +If[(lang == "shell" || lang == "CCL"), + com1 = "#"; com2 = ""; +]; + +{com1 <> " file produced by user " <> user[] <> ", " <> date[] <> com2 <> "\n" <> + com1 <> " Produced with Mathematica Version " <> ToString[$Version] <> com2 <> "\n\n"<> + com1 <> " Mathematica script written by Ian Hinder and Sascha Husa" <> com2 <> "\n\n"<> + com1 <> " $Id" <> "$" <> com2 <> "\n\n"} + +]; + + +(* ------------------------------------------------------------------------ + Makefile + ------------------------------------------------------------------------ *) + +(* Return a CodeGen block representing a makefile which refers to the + list of filenames sourceFiles *) +CreateMakefile[sourceFiles_] := + {whoWhen["shell"], + "SRCS = ", Map[{#, " "} &, sourceFiles]}; + +(* ------------------------------------------------------------------------ + Parameter file + ------------------------------------------------------------------------ *) + +(* parameterFileSpec = {Implementations -> {}, NewParameters -> {}} + + implementation = {Name -> "", + UsedParameters (optional) -> {spec1, spec2, ...}, + ExtendedParameters (optional) -> {spec1, spec2, ...}} + + (optional) allowedValue = {Value -> "", Description -> ""} + + parameter spec = {Name -> "", Type -> "", Default -> "", + Description -> "", Visibility -> "private", + AllowedValues -> {...}} *) + +(* Return a CodeGen block which represents the quoted value of x *) +Quote[x_] := {"\"", x, "\""}; + +(* To be used for parameters; will quote it if it is a keyword *) +renderValue[type_, value_] := + If[type == "KEYWORD", + Quote[value], + value]; + +(* Return a block defining a parameter with the given + parameterSpec (defined above). This is used for defining new + parameters, as well as extending existing ones. *) +parameterBlock[spec_] := + {lookup[spec, Type], " ", + lookup[spec, Name], " ", + Quote[lookup[spec, Description]], + + If[mapContains[spec, AccumulatorBase], + {" ACCUMULATOR-BASE=", lookup[spec, AccumulatorBase]}, + {}], + + "\n", + SuffixedCBlock[ + + (* For each allowed value of the parameter specified in the spec, + create a line with the value and the description *) + Map[{renderValue[lookup[spec,Type], lookup[#, Value]], " :: ", + Quote[lookup[#, Description]], "\n"} &, + lookupDefault[spec, AllowedValues, {}]], + + (* Output the line describing the default value of the parameter *) + renderValue[lookup[spec,Type], lookup[spec, Default]]], + + "\n"}; + +(* Given a particular implementation, return a CodeGen block defining + which parameters are used or extended from that implementation *) +parameterImplementationSection[spec_] := + {"\nshares: ", lookup[spec, Name], "\n", "\n", + + (* For each used parameter in the spec, output a line indicating + that it is used *) + Map[{"USES ", lookup[#, Type], " ", lookup[#, Name], "\n"} &, + lookupDefault[spec, UsedParameters, {}]], "\n", + + (* For each extended parameter in the spec, output a parameter + block containing the specified extension prefixed with EXTENDS *) + Map[{"EXTENDS ", parameterBlock[#], "\n"} &, + lookupDefault[spec, ExtendedParameters, {}]]}; + +(* Given a parameterFileSpec structure, return a CodeGen block for the + param.ccl file *) +CreateParam[spec_] := + {whoWhen["CCL"], + + (* For each implementation defined in the spec, output a block + which declares which parameters are used and extended by this + implementation *) + Map[parameterImplementationSection, + lookupDefault[spec, Implementations, {}]], + + (* For each new parameter being defined by this implementation, + output a parameter block for it *) + Map[{lookup[#, Visibility], ":\n", parameterBlock[#]} &, + lookupDefault[spec, NewParameters, {}]]}; + +(* ------------------------------------------------------------------------ + Interface file + ------------------------------------------------------------------------ *) + +(* The following "group" structure defines a Cactus group of variables + to be included in an interface.ccl file. + + group: + + {Name -> "", VariableType -> "", Timelevels -> 2, GridType -> "GF", + Comment -> "", Visibility -> "public" + Variables -> {phi, h11, ...}} *) + +(* Given the specification of a group structure, return a CodeGen + block for the interface.ccl file to define that group *) +interfaceGroupBlock[spec_] := + {lookup[spec, Visibility], ":\n", + lookup[spec, VariableType], " ", lookup[spec, Name], + " type=", lookup[spec,GridType], " ", + "timelevels=", lookup[spec, Timelevels], "\n", + SuffixedCBlock[{CommaNewlineSeparated[lookup[spec, Variables]],"\n"}, + "\"" <> lookup[spec, Comment] <> "\""]}; + +(* Function aliasing *) + +(* A definition of an aliased function is: + + {Name -> "MoLRegisterEvolvedGroup", + Type -> "CCTK_INT", + ArgString -> "CCTK_INT IN EvolvedIndex, CCTK_INT IN RHSIndex"} + +*) + +usesFunction[f_] := + {lookup[f, Type], " FUNCTION ", lookup[f, Name], "(", lookup[f,ArgString], ")\n", + "USES FUNCTION ", lookup[f, Name], "\n\n"}; + + +(* Given the name of an implementation, a list of implementation names + that we inherit from, a list of include files to mention, and a + list of group structures as defined above, return a CodeGen block + representing the interface.ccl file. As an optional argument, one + can specify Friends -> {list of implementations we want as + friends}. Can also have UsesFunction -> {functions}*) +CreateInterface[implementation_, inheritedImplementations_, includeFiles_, + groups_, opts___] := + {whoWhen["CCL"], + "implements: ", implementation, "\n\n", + "inherits: ", SpaceSeparated[inheritedImplementations], "\n\n", + If[mapContains[{opts}, Friends], + {"friend: ", SpaceSeparated[lookup[{opts}, Friends]]},{}], + "\n\n", + Map[{"USES INCLUDE: ", #, "\n"} &, includeFiles], + "\n", + + Map[usesFunction, lookupDefault[{opts}, UsesFunctions, {}]], + + + NewlineSeparated[Map[FlattenBlock[interfaceGroupBlock[#]] &, groups]]}; + +(* ------------------------------------------------------------------------ + Scheduling + ------------------------------------------------------------------------ *) + +(* storage group + + (represents the fact that we want to allocate storage for a Cactus + variable group with the given number of timelevels) + + {Group -> "admbase::metric", Timelevels -> 3, + Conditional -> {Parameter -> "", Value -> ""}, + Conditional -> {Textual -> "CCTK_EQUALS(name,value)"}} + + A "conditional" structure looks like this: {Parameter -> "", Value -> ""} + + scheduled function: (a function to be scheduled at a particular point) + + {Name -> "ADM_BSSN_CalcRHS_fn", SchedulePoint -> "in POSTINITIAL before ExternalLapse", + Language -> "C", Comment -> "", + (optional) SynchronizedGroups -> {ADM_BSSN_gamma, ...}, + (optional) StorageGroups -> {Group -> "mygroup", Timelevels -> 1}, + (optional) Conditional -> {Parameter -> "", Value -> ""}} + + scheduled group: + + {... sameish} + +*) + +(* Given a storage group structure defined above, return a CodeGen + structure for inclusion in the schedule.ccl file to allocate + storage for this group. *) +groupStorage[spec_] := + {"STORAGE: ", lookup[spec, Group], "[", lookup[spec, Timelevels], "]\n"} + + +(* Given a function scheduling specification as defined above, return + a CodeGen block to schedule the function for the schedule.ccl file *) +scheduleUnconditionalFunction[spec_] := + {"schedule ", lookup[spec, Name], " ", lookup[spec,SchedulePoint], "\n", + SuffixedCBlock[ + {"LANG: ", lookup[spec, Language], "\n\n", + + (* Insert a SYNC line for each group we want to synchronize. *) + Map[{"SYNC: ", #, "\n"} &, lookupDefault[spec, SynchronizedGroups, {}]], + + Map[{"TRIGGERS: ", #, "\n"} &, lookupDefault[spec, TriggerGroups, {}]], + + (* Insert a storage block for each group we want to allocate + storage for *) + Map[groupStorage, lookupDefault[spec, StorageGroups, {}]]}, + + Quote[lookup[spec, Comment]]]}; + +(* Handle the aspect of scheduling the function conditionally *) +scheduleFunction[spec_] := + Module[{condition, parameter, value, u}, + + u = scheduleUnconditionalFunction[spec]; + + If[mapContains[spec, Conditional], + + (* Output the conditional structure *) + condition = lookup[spec, Conditional]; + + If[mapContains[condition, Textual], + + ConditionalOnParameterTextual[lookup[condition, Textual], u], + + If[mapContains[condition, Parameter], + + parameter = lookup[condition, Parameter]; + value = lookup[condition, Value]; + ConditionalOnParameter[parameter, value, u], + + If[condition != {}, + Throw["Unrecognized conditional structure", condition], + u]]], + u]]; + + +(* Schedule a schedule group. Use a slightly dirty trick; given that + the structure is identical to that for a function except with the + word "GROUP" added before the function name, just use the existing + function. *) +scheduleGroup[spec_] := + scheduleFunction[mapReplace[spec, Name, "group " <> lookup[spec, Name]]]; + +(* Taking a list of group storage specifications for global storage, + and lists of scheduled function and scheduled group structures, + return a CodeGen block representing a schdule.ccl file. *) +CreateSchedule[globalStorageGroups_, scheduledGroups_, scheduledFunctions_] := + {whoWhen["CCL"], + Map[SeparatedBlock[groupStorage[#]] &, globalStorageGroups], + Map[SeparatedBlock[scheduleFunction[#]] &, scheduledFunctions], + Map[SeparatedBlock[scheduleGroup[#]] &, scheduledGroups]}; + + +(* ------------------------------------------------------------------------ + Setter + ------------------------------------------------------------------------ *) + +(* calculation = {Name -> "ClassicADM_Setter", + optional Before -> {functions}, + optional After -> {functions}, + Shorthands -> {gInv11, ...}, + GridFunctions -> {g11rhs, K11}, + CollectList -> {hInv11, hInv22, ...}, + optional DeclarationIncludes -> {include file list}, + optional LoopPreIncludes -> {include file list}, + Equations -> {{K11_rhs -> 2 A K11, ...}...}} *) + +calculationMacros[] := + CommentedBlock["Define macros used in calculations", + Map[{"#define ", #, "\n"} &, + {"INITVALUE (42)", + "INV(x) ((1) / (x))" , + "SQR(x) ((x) * (x))" , + "CUB(x) ((x) * (x) * (x))" , + "QAD(x) ((x) * (x) * (x) * (x))"}]]; + +(* Given a list of Calculation structures as defined above, create a + CodeGen representation of a source file that defines a function for + each Calculation. *) + +CreateSetterSource[calcs_, debug_] := + {whoWhen[CodeGen`SOURCELANGUAGE], + + "#define KRANC_" <> ToUpperCase[CodeGen`SOURCELANGUAGE] <> "\n\n", + + If[CodeGen`SOURCELANGUAGE == "C", + IncludeFile["math.h"], + "\n" + ], + + Map[IncludeFile, {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h", + "precomputations.h", "GenericFD.h"}], + calculationMacros[], + + (* For each function structure passed, create the function and + insert it *) + Map[CreateCalculationFunction[# , debug]& , + calcs]}; + + + +(* ------------------------------------------------------------------------ + Symmetries Registration + ------------------------------------------------------------------------ *) + +(* Symmetries registration spec = {{FullName -> "impl::GFname", + Sym -> {symX, symY, symZ}}, ...} *) + +SymmetriesBlock[spec_] := + + Module[{i, KrancDim}, + + KrancDim = 3; + + sym = lookup[spec, Sym]; + + {Table["sym[" <> ToString[i - 1] <> "] = " <> + ToString@sym[[i]] <> ";\n", {i, 1, KrancDim}], + + "SetCartSymVN(cctkGH, sym, \"" <> lookup[spec, FullName] <> "\");\n\n" +} +]; + + +calcSymmetry[gf_] := Module[{sym, q, string}, + +sym = {1, 1, 1}; (* default *) + +string = ToString@gf; + +While[IntegerQ[q = ToExpression@StringTake[string, -1]], + +Module[{}, + sym[[q]] = -sym[[q]]; + string = StringDrop[string, -1] + ] +]; +sym +]; + + +(* Given a symmetries registration structure as defined above, return a + C CodeGen structure of a source file which will register the symmetries. *) +CreateSymmetriesRegistrationSource[thornName_, implementationName_, GFs_, debug_] := + + Module[{spec, j, lang, tmp}, + + If[debug, + Print["Registering Symmetries for: ", GFs]; + ]; + + lang = CodeGen`SOURCELANGUAGE; + CodeGen`SOURCELANGUAGE = "C"; + + spec = Table[{FullName -> implementationName <> "::" <> ToString@GFs[[j]], + Sym -> calcSymmetry[GFs[[j]] ] + }, {j, 1, Length@GFs}]; + + tmp = {whoWhen["C"], + + Map[IncludeFile, + {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h", "Symmetry.h"}], + + DefineCCTKFunction[ thornName <> "_RegisterSymmetries", "void", + {CommentedBlock["array holding symmetry definitions", + + "CCTK_INT sym[3];\n\n"], + + CommentedBlock["Register symmetries of grid functions", + + Map[SymmetriesBlock, spec]]} +] + }; + + CodeGen`SOURCELANGUAGE = lang; + +tmp +]; + + +(* ------------------------------------------------------------------------ + 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 = CodeGen`SOURCELANGUAGE; + CodeGen`SOURCELANGUAGE= "C"; + + tmp = {whoWhen["C"], + + Map[IncludeFile, + {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h"}], + + DefineCCTKFunction[lookup[spec,ThornName] <> "_RegisterVars", "CCTK_INT", + {DefineVariable["ierr", "CCTK_INT", "0"], + + CommentedBlock["Register all the evolved grid functions with MoL", + + Map[{"ierr += MoLRegisterEvolved(CCTK_VarIndex(\"", + lookup[spec,BaseImplementation], "::", #, "\"), CCTK_VarIndex(\"", + lookup[spec,BaseImplementation], "::", #, "rhs\"));\n"} &, + lookup[spec, EvolvedGFs]]], + + CommentedBlock["Register all the primitive grid functions with MoL", + Map[{"ierr += MoLRegisterConstrained(CCTK_VarIndex(\"", + lookup[spec,BaseImplementation], "::", #, "\"));\n"} &, + lookup[spec, PrimitiveGFs]]], + "return ierr;\n"}]}; + + CodeGen`SOURCELANGUAGE = lang; + +tmp +]; + +(* ------------------------------------------------------------------------ + MoL Boundaries + ------------------------------------------------------------------------ *) +(* currently this only does periodic boundaries, i.e. provides + a place for SYNCing evolution variables *) + +(* 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. radiative + +To simplify scheduling, testing, etc. the 3 steps are currently applied +in separate functions! +*) + +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[{groups, tmp, lang}, + + groups = lookup[spec, Groups]; + groups = Map[lookup[spec, BaseImplementation] <> "::" <> ToString@# &, groups]; + + noBCGroup[group_] := + " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, -1, \"" <> + ToString@group <> "\",\t\"None\");\n"; + + + flatBCGroup[group_] := + " ierr = Boundary_SelectGroupForBC(cctkGH, CCTK_ALL_FACES, 1, -1, \"" <> + ToString@group <> "\",\t\"Flat\");\n"; + + lang = CodeGen`SOURCELANGUAGE; + CodeGen`SOURCELANGUAGE = "C"; + + tmp = {whoWhen["C"], + + + Map[IncludeFile, + {"cctk.h", "cctk_Arguments.h", "cctk_Parameters.h", + "cctk_Faces.h", "util_Table.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", + "CCTK_INT", + {"/* check whether we can use excision */\n\n", + "#ifdef EXCISION_LEGOEXCISION\n", + "CCTK_INFO(\"Compiled with LegoExcision\");\n", + "#endif\n", + "\n", + "return 0;\n"}], + + + cleanCPP@DefineCCTKFunction[lookup[spec,ThornName] <> "_ApplyBoundConds", + "CCTK_INT", + {DefineVariable["ierr", "CCTK_INT", "0"], + + "\n", + "if (CCTK_EQUALS(bound, \"none\" ) ||\n", + " CCTK_EQUALS(bound, \"static\") ||\n", + " CCTK_EQUALS(bound, \"zero\" ) ) \n", + "{\n", + " /* None or static: Do nothing, as well for Zero - why?? */\n", + + Map[noBCGroup, groups], + + "}\n", + + "else if(CCTK_EQUALS(bound, \"flat\"))\n", + "{\n", + " /* Flat BCs ... what was it that they do?? */\n", + + Map[flatBCGroup, groups], + + "}\n", + + + "return ierr;\n"}] + }; + + CodeGen`SOURCELANGUAGE = lang; +tmp +]; + +CreateMoLExcisionSource[spec_] := + + Module[{gfs, currentlang, body, excisionExtrap}, + + gfs = lookup[spec, ExcisionGFs]; + + Print["Applying excision to GFs: ", gfs]; + + currentlang = CodeGen`SOURCELANGUAGE; + CodeGen`SOURCELANGUAGE = "Fortran"; + + excisionExtrap[gf_] := "call excision_extrapolate(ierr, " + <> ToString@gf <> ", " <> ToString@gf + <> "_p, emask, exnormx, exnormy, exnormz, nx, ny, nz, v0)\n"; + + body = {whoWhen["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\n", + "! to simplify scheduling and testing, the 3 steps \n", + "! are currently applied in separate functions \n\n"}, + + + cleanCPP@DefineCCTKSubroutine[lookup[spec,ThornName] <> "_ApplyExcision", + {"#ifdef EXCISION_LEGOEXCISION\n", + "! APPLY EXCISION\n\n", + DefineVariable["ierr", "CCTK_INT", "0"], + "", + + "integer :: nx, ny, nz\n\n", + "CCTK_REAL :: v0 = 0.0d0 ! constant value used within excision mask\n\n", + + "! grid parameters\n", + + "nx = cctk_lsh(1)\n", + "ny = cctk_lsh(2)\n", + "nz = cctk_lsh(3)\n\n", + + "call excision_findboundary(ierr, emask, nx, ny, nz)\n", + "call excision_findnormals (ierr, emask, exnormx, exnormy, exnormz, nx, ny, nz)", + "\n\n", + + Map[excisionExtrap, gfs], + "", + "#endif\n\n", + "return\n", + "end subroutine\n"}] +}; + +CodeGen`SOURCELANGUAGE = currentlang; + +body +]; + + + +(* -------------------------------------------------------------------------- + Precompmacros + -------------------------------------------------------------------------- *) + +(* Argument to this is the same as for CreateSetterSource. This is + not implemented currently because the precomputations are performed + in the setter file itself. We want to change this for readability + reasons. The change will be to have this precompMacros.h file + define a macro performing the precomputations for *each loop* in + each function. Then the setter source file just has a line + invoking the macro in each loop. *) +CreatePrecompMacros[functions_] := + Module[{}, + {}]; + +(* ------------------------------------------------------------------------ + Startup file + ------------------------------------------------------------------------ *) + +CreateStartupFile[thornName_, bannerText_] := + Module[{tmp, lang}, + + lang = CodeGen`SOURCELANGUAGE; + CodeGen`SOURCELANGUAGE = "C"; + + tmp = {whoWhen["C"], + + IncludeFile["cctk.h"], + DefineFunction[thornName <> "_Startup", "int", "void", + {DefineVariable["banner", "const char *", Quote[bannerText]], + "CCTK_RegisterBanner(banner);\n", + "return 0;\n"}]}; + + CodeGen`SOURCELANGUAGE = lang; + + tmp + ]; + +(* ------------------------------------------------------------------------ + Thorn creation + ------------------------------------------------------------------------ *) + +(* source = {Filename -> "MoLRegister.c", Contents -> "#include ..."} *) + +(* thorn = {Name -> "ClassicADMMolEvolve", Directory -> "ClassicADM", + Interface -> i, Schedule -> s, Param -> p, Makefile -> m, + Sources -> {s1, s2, ...} *) + +(* Given a thorn specification structure as defined above, create a + thorn. Note that if you specify a path to the thorn, then you are + responsible for making sure that the parent directory exists; this + function does not automatically create any parent directories. *) +CreateThorn[thorn_] := + Module[{thornDirectory, sourceDirectory}, + + thornDirectory = lookup[thorn, Directory] <> "/" <> lookup[thorn, Name]; + sourceDirectory = thornDirectory <> "/src"; + + Print["Creating thorns in directory ", thornDirectory]; + + ensureDirectory[thornDirectory]; + ensureDirectory[sourceDirectory]; + + GenerateFile[thornDirectory <> "/interface.ccl", lookup[thorn, Interface]]; + GenerateFile[thornDirectory <> "/param.ccl", lookup[thorn, Param]]; + GenerateFile[thornDirectory <> "/schedule.ccl", lookup[thorn, Schedule]]; + + Map[GenerateFile[sourceDirectory <> "/" <> lookup[#, Filename], + lookup[#, Contents]] &, + lookup[thorn, Sources]]; + + GenerateFile[sourceDirectory <> "/make.code.defn", lookup[thorn, Makefile]]]; + +End[]; + +EndPackage[]; |