diff --git a/makefile b/makefile index c2befaa55..fb1d88f5e 100644 --- a/makefile +++ b/makefile @@ -43,7 +43,7 @@ make solvers Builds each solver executable. make {solver} Builds a solver executable, - solver can be acoustics/advection/bns/cns/elliptic/fokkerPlanck/gradient/ins. + solver can be acoustics/advection/bns/cns/elliptic/fokkerPlanck/gradient/ins/maxwell. make clean Cleans all solver executables, libraries, and object files. make clean-{solver} @@ -64,7 +64,7 @@ Can use "make verbose=true" for verbose output. endef ifeq (,$(filter solvers \ - acoustics advection bns cns elliptic fokkerPlanck gradient ins \ + acoustics advection bns cns elliptic fokkerPlanck gradient ins maxwell \ lib clean clean-kernels \ realclean info help test,$(MAKECMDGOALS))) ifneq (,$(MAKECMDGOALS)) @@ -88,12 +88,12 @@ LIBP_CORE_LIBS=timeStepper linearSolver parAlmond mesh ogs linAlg core SOLVER_DIR =${LIBP_DIR}/solvers .PHONY: all solvers libp_libs \ - acoustics advection bns lbs cns elliptic fokkerPlanck gradient ins \ + acoustics advection bns lbs cns elliptic fokkerPlanck gradient ins maxwell\ clean clean-libs realclean help info all: solvers -solvers: acoustics advection bns lbs cns elliptic fokkerPlanck gradient ins +solvers: acoustics advection bns lbs cns elliptic fokkerPlanck gradient ins maxwell libp_libs: ifneq (,${verbose}) @@ -174,10 +174,19 @@ else @${MAKE} -C ${SOLVER_DIR}/$(@F) --no-print-directory endif +maxwell: libp_libs +ifneq (,${verbose}) + ${MAKE} -C ${SOLVER_DIR}/$(@F) verbose=${verbose} +else + @printf "%b" "$(SOL_COLOR)Building $(@F) solver$(NO_COLOR)\n"; + @${MAKE} -C ${SOLVER_DIR}/$(@F) --no-print-directory +endif + + #cleanup clean: clean-acoustics clean-advection clean-bns clean-lbs clean-cns \ clean-elliptic clean-fokkerPlanck clean-gradient clean-ins \ - clean-libs + clean-maxwell clean-libs clean-acoustics: ${MAKE} -C ${SOLVER_DIR}/acoustics clean @@ -206,6 +215,9 @@ clean-gradient: clean-ins: ${MAKE} -C ${SOLVER_DIR}/ins clean +clean-maxwell: + ${MAKE} -C ${SOLVER_DIR}/maxwell clean + clean-libs: ${MAKE} -C ${LIBP_LIBS_DIR} clean diff --git a/solvers/maxwell/data/maxwellGaussian2D.h b/solvers/maxwell/data/maxwellGaussian2D.h new file mode 100644 index 000000000..965387690 --- /dev/null +++ b/solvers/maxwell/data/maxwellGaussian2D.h @@ -0,0 +1,45 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + + +// Boundary conditions +/* PEC 1 */ +#define maxwellDirichletConditions2D(bc, t, x, y, nx, ny, HxM, HyM, EzM, HxB, HyB, EzB) \ + { \ + if(bc==1){ \ + *(HxB) = HxM; \ + *(HyB) = HyM; \ + *(EzB) = -EzM; \ + } \ + } + +// Initial conditions +#define maxwellInitialConditions2D(t, x, y, Hx, Hy, Ez) \ + { \ + *(Hx) = 0.0; \ + *(Hy) = 0.0; \ + *(Ez) = exp(-3*(x*x+y*y)); \ + } diff --git a/solvers/maxwell/data/maxwellGaussian3D.h b/solvers/maxwell/data/maxwellGaussian3D.h new file mode 100644 index 000000000..c834ee9c8 --- /dev/null +++ b/solvers/maxwell/data/maxwellGaussian3D.h @@ -0,0 +1,52 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + + + +// Boundary conditions +/* PEC=1 */ +#define maxwellDirichletConditions3D(bc, t, x, y, z, nx, ny, nz, HxM, HyM, HzM, ExM, EyM, EzM, HxB, HyB, HzB, ExB, EyB, EzB) \ + { \ + if(bc==1){ \ + *(HxB) = HxM; \ + *(HyB) = HyM; \ + *(HzB) = HzM; \ + *(ExB) = -ExM; \ + *(EyB) = -EyM; \ + *(EzB) = -EzM; \ + } \ + } + +// Initial conditions +#define maxwellInitialConditions3D(t, x, y, z, Hx, Hy, Hz, Ex, Ey, Ez) \ + { \ + *(Hx) = 0.0; \ + *(Hy) = 0.0; \ + *(Hz) = 0.0; \ + *(Ex) = 0.0; \ + *(Ey) = 0.0; \ + *(Ez) = exp(-3*(x*x+y*y+z*z)); \ + } diff --git a/solvers/maxwell/data/maxwellMode2D.h b/solvers/maxwell/data/maxwellMode2D.h new file mode 100644 index 000000000..a45cd4910 --- /dev/null +++ b/solvers/maxwell/data/maxwellMode2D.h @@ -0,0 +1,48 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + + + +// Boundary conditions +/* PEC=1 */ +#define maxwellDirichletConditions2D(bc, t, x, y, nx, ny, HxM, HyM, EzM, HxB, HyB, EzB) \ + { \ + if(bc==1){ \ + *(HxB) = HxM; \ + *(HyB) = HyM; \ + *(EzB) = -EzM; \ + } \ + } + +// Initial conditions +#define maxwellInitialConditions2D(t, x, y, Hx, Hy, Ez) \ + { \ + dfloat n = 1., m = 2.; \ + dfloat omega = M_PI*sqrt(n*n+m*m); \ + *(Hx) = -M_PI*n*sin(m*M_PI*x)*cos(n*M_PI*y)*sin(omega*t)/omega; \ + *(Hy) = M_PI*m*cos(m*M_PI*x)*sin(n*M_PI*y)*sin(omega*t)/omega; \ + *(Ez) = sin(m*M_PI*x)*sin(n*M_PI*y)*cos(omega*t); \ + } diff --git a/solvers/maxwell/data/maxwellMode3D.h b/solvers/maxwell/data/maxwellMode3D.h new file mode 100644 index 000000000..12737c5d6 --- /dev/null +++ b/solvers/maxwell/data/maxwellMode3D.h @@ -0,0 +1,54 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + + + +// Boundary conditions +/* PEC=1 */ +#define maxwellDirichletConditions3D(bc, t, x, y, z, nx, ny, nz, HxM, HyM, HzM, ExM, EyM, EzM, HxB, HyB, HzB, ExB, EyB, EzB) \ + { \ + if(bc==1){ \ + *(HxB) = HxM; \ + *(HyB) = HyM; \ + *(HzB) = HzM; \ + *(ExB) = -ExM; \ + *(EyB) = -EyM; \ + *(EzB) = -EzM; \ + } \ + } + +// Initial conditions +#define maxwellInitialConditions3D(t, x, y, z, Hx, Hy, Hz, Ex, Ey, Ez) \ + { \ + dfloat n = 1., m = 2.; \ + const dfloat omega = M_PI*sqrt(n*n+m*m); \ + *(Hx) = -M_PI*n*sin(m*M_PI*x)*cos(n*M_PI*y)*sin(omega*t)/omega; \ + *(Hy) = M_PI*m*cos(m*M_PI*x)*sin(n*M_PI*y)*sin(omega*t)/omega; \ + *(Hz) = 0; \ + *(Ex) = 0; \ + *(Ey) = 0; \ + *(Ez) = sin(m*M_PI*x)*sin(n*M_PI*y)*cos(omega*t); \ + } diff --git a/solvers/maxwell/makefile b/solvers/maxwell/makefile new file mode 100644 index 000000000..1f99d2f91 --- /dev/null +++ b/solvers/maxwell/makefile @@ -0,0 +1,175 @@ +##################################################################################### +# +#The MIT License (MIT) +# +#Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus +# +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. +# +##################################################################################### + +define MAXWELL_HELP_MSG + +Maxwell solver makefile targets: + + make maxwellMain (default) + make lib + make clean + make clean-libs + make clean-kernels + make realclean + make info + make help + make test + +Usage: + +make maxwellMain + Build maxwellMain executable. +make lib + Build libmaxwell.a solver library. +make clean + Clean the maxwellMain executable, library, and object files. +make clean-libs + In addition to "make clean", also clean needed libraries. +make clean-kernels + In addition to "make clean-libs", also cleans the cached OCCA kernels. +make realclean + In addition to "make clean-kernels", also clean 3rd party libraries. +make info + List directories and compiler flags in use. +make help + Display this help message. +make test + Run tests. +Can use "make verbose=true" for verbose output. + +endef + +ifeq (,$(filter maxwellMain lib clean clean-libs clean-kernels \ + realclean info help test,$(MAKECMDGOALS))) +ifneq (,$(MAKECMDGOALS)) +$(error ${MAXWELL_HELP_MSG}) +endif +endif + +ifndef LIBP_MAKETOP_LOADED +ifeq (,$(wildcard ../../make.top)) +$(error cannot locate ${PWD}/../../make.top) +else +include ../../make.top +endif +endif + +#libraries +MAXWELL_LIBP_LIBS=timeStepper mesh parAdogs ogs linAlg core + +#includes +INCLUDES=${LIBP_INCLUDES} \ + -I. + +#defines +DEFINES =${LIBP_DEFINES} \ + -DLIBP_DIR='"${LIBP_DIR}"' + +#.cpp compilation flags +MAXWELL_CXXFLAGS=${LIBP_CXXFLAGS} ${DEFINES} ${INCLUDES} + +#link libraries +LIBS=-L${LIBP_LIBS_DIR} $(addprefix -l,$(MAXWELL_LIBP_LIBS)) \ + ${LIBP_LIBS} + +#link flags +LFLAGS=${MAXWELL_CXXFLAGS} ${LIBS} + +#object dependancies +DEPS=$(wildcard *.hpp) \ + $(wildcard $(LIBP_INCLUDE_DIR)/*.h) \ + $(wildcard $(LIBP_INCLUDE_DIR)/*.hpp) + +SRC =$(wildcard src/*.cpp) + +OBJS=$(SRC:.cpp=.o) + +.PHONY: all lib libp_libs clean clean-libs \ + clean-kernels realclean help info + +all: maxwellMain + +lib: libmaxwell.a + +libp_libs: +ifneq (,${verbose}) + ${MAKE} -C ${LIBP_LIBS_DIR} $(MAXWELL_LIBP_LIBS) verbose=${verbose} +else + @${MAKE} -C ${LIBP_LIBS_DIR} $(MAXWELL_LIBP_LIBS) --no-print-directory +endif + +maxwellMain:$(OBJS) maxwellMain.o libp_libs +ifneq (,${verbose}) + $(LIBP_LD) -o maxwellMain maxwellMain.o $(OBJS) $(MESH_OBJS) $(LFLAGS) +else + @printf "%b" "$(EXE_COLOR)Linking $(@F)$(NO_COLOR)\n"; + @$(LIBP_LD) -o maxwellMain maxwellMain.o $(OBJS) $(MESH_OBJS) $(LFLAGS) +endif + +libmaxwell.a: $(OBJS) +ifneq (,${verbose}) + ar -cr libmaxwell.a $(OBJS) +else + @printf "%b" "$(LIB_COLOR)Building library $(@F)$(NO_COLOR)\n"; + @ar -cr libmaxwell.a $(OBJS) +endif + +# rule for .cpp files +%.o: %.cpp $(DEPS) | libp_libs +ifneq (,${verbose}) + $(LIBP_CXX) -o $*.o -c $*.cpp $(MAXWELL_CXXFLAGS) +else + @printf "%b" "$(OBJ_COLOR)Compiling $(@F)$(NO_COLOR)\n"; + @$(LIBP_CXX) -o $*.o -c $*.cpp $(MAXWELL_CXXFLAGS) +endif + +#cleanup +clean: + rm -f src/*.o *.o maxwellMain libmaxwell.a + +clean-libs: clean + ${MAKE} -C ${LIBP_LIBS_DIR} clean + +clean-kernels: clean-libs + rm -rf ${LIBP_DIR}/.occa/ + +realclean: clean + ${MAKE} -C ${LIBP_LIBS_DIR} realclean + +help: + $(info $(value MAXWELL_HELP_MSG)) + @true + +info: + $(info OCCA_DIR = $(OCCA_DIR)) + $(info LIBP_DIR = $(LIBP_DIR)) + $(info LIBP_ARCH = $(LIBP_ARCH)) + $(info CXXFLAGS = $(MAXWELL_CXXFLAGS)) + $(info LIBS = $(LIBS)) + @true + +test: maxwellMain + @${MAKE} -C $(LIBP_TEST_DIR) --no-print-directory test-maxwell diff --git a/solvers/maxwell/maxwell.hpp b/solvers/maxwell/maxwell.hpp new file mode 100644 index 000000000..ab0966137 --- /dev/null +++ b/solvers/maxwell/maxwell.hpp @@ -0,0 +1,90 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#ifndef MAXWELL_HPP +#define MAXWELL_HPP 1 + +#include "core.hpp" +#include "platform.hpp" +#include "mesh.hpp" +#include "solver.hpp" +#include "timeStepper.hpp" +#include "linAlg.hpp" + +#define DMAXWELL LIBP_DIR"/solvers/maxwell/" + +using namespace libp; + +class maxwellSettings_t: public settings_t { +public: + maxwellSettings_t(comm_t _comm); + void report(); + void parseFromFile(platformSettings_t& platformSettings, + meshSettings_t& meshSettings, + const std::string filename); +}; + +class maxwell_t: public solver_t { +public: + mesh_t mesh; + + int Nfields; + + timeStepper_t timeStepper; + + ogs::halo_t traceHalo; + + memory q; + deviceMemory o_q; + + kernel_t volumeKernel; + kernel_t surfaceKernel; + + kernel_t initialConditionKernel; + kernel_t errorKernel; + + maxwell_t() = default; + maxwell_t(platform_t &_platform, mesh_t &_mesh, + maxwellSettings_t& _settings) { + Setup(_platform, _mesh, _settings); + } + + //setup + void Setup(platform_t& _platform, mesh_t& _mesh, + maxwellSettings_t& _settings); + + void Run(); + + void Report(dfloat time, int tstep); + + void PlotFields(memory Q, const std::string fileName); + + void rhsf(deviceMemory& o_q, deviceMemory& o_rhs, const dfloat time); + + dfloat MaxWaveSpeed(); +}; + +#endif diff --git a/solvers/maxwell/maxwellMain.cpp b/solvers/maxwell/maxwellMain.cpp new file mode 100644 index 000000000..2f5b4d599 --- /dev/null +++ b/solvers/maxwell/maxwellMain.cpp @@ -0,0 +1,68 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "maxwell.hpp" + +int main(int argc, char **argv){ + + // start up MPI + Comm::Init(argc, argv); + + LIBP_ABORT("Usage: ./maxwellMain setupfile", argc!=2); + + { /*Scope so everything is destructed before MPI_Finalize */ + comm_t comm(Comm::World().Dup()); + + //create default settings + platformSettings_t platformSettings(comm); + meshSettings_t meshSettings(comm); + maxwellSettings_t maxwellSettings(comm); + + //load settings from file + maxwellSettings.parseFromFile(platformSettings, meshSettings, + argv[1]); + + // set up platform + platform_t platform(platformSettings); + + platformSettings.report(); + meshSettings.report(); + maxwellSettings.report(); + + // set up mesh + mesh_t mesh(platform, meshSettings, comm); + + // set up maxwell solver + maxwell_t maxwell(platform, mesh, maxwellSettings); + + // run + maxwell.Run(); + } + + // close down MPI + Comm::Finalize(); + return LIBP_SUCCESS; +} diff --git a/solvers/maxwell/okl/maxwellErrorTet3D.okl b/solvers/maxwell/okl/maxwellErrorTet3D.okl new file mode 100644 index 000000000..119696532 --- /dev/null +++ b/solvers/maxwell/okl/maxwellErrorTet3D.okl @@ -0,0 +1,151 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + + +// isotropic maxwell +@kernel void maxwellErrorTet3D(const dlong Nelements, + const dfloat time, + @restrict const dfloat * vgeo, + @restrict const dfloat * x, + @restrict const dfloat * y, + @restrict const dfloat * z, + @restrict const dfloat * MM, + @restrict const dfloat * q, + @restrict dfloat * normerrq){ + + for(dlong e=0;e512 + for(int n=0;n256 + for(int n=0;n128 + for(int n=0;n64 + for(int n=0;n32 + for(int n=0;n16 + for(int n=0;n8 + for(int n=0;n4 + for(int n=0;n2 + for(int n=0;n1 + for(int n=0;n512 + for(int n=0;n256 + for(int n=0;n128 + for(int n=0;n64 + for(int n=0;n32 + for(int n=0;n16 + for(int n=0;n8 + for(int n=0;n4 + for(int n=0;n2 + for(int n=0;n1 + for(int n=0;n full upwinding + + ndotdH = nx.*dHx + ny.*dHy + nz.*dHz; + ndotdE = nx.*dEx + ny.*dEy + nz.*dEz; + + fluxHx = -ny.*dEz + nz.*dEy + alpha*(dHx - ndotdH.*nx); + fluxHy = -nz.*dEx + nx.*dEz + alpha*(dHy - ndotdH.*ny); + fluxHz = -nx.*dEy + ny.*dEx + alpha*(dHz - ndotdH.*nz); + + fluxEx = ny.*dHz - nz.*dHy + alpha*(dEx - ndotdE.*nx); + fluxEy = nz.*dHx - nx.*dHz + alpha*(dEy - ndotdE.*ny); + fluxEz = nx.*dHy - ny.*dHx + alpha*(dEz - ndotdE.*nz); + */ + + // form field differences at faces + dfloat dHx = HxP - HxM, dEx = ExP - ExM; + dfloat dHy = HyP - HyM, dEy = EyP - EyM; + dfloat dHz = HzP - HzM, dEz = EzP - EzM; + + dfloat alpha=1; // => full upwinding + + dfloat ndotdH = nx*dHx + ny*dHy + nz*dHz; + dfloat ndotdE = nx*dEx + ny*dEy + nz*dEz; + + *fluxHx = -ny*dEz + nz*dEy + alpha*(dHx - ndotdH*nx); + *fluxHy = -nz*dEx + nx*dEz + alpha*(dHy - ndotdH*ny); + *fluxHz = -nx*dEy + ny*dEx + alpha*(dHz - ndotdH*nz); + + *fluxEx = ny*dHz - nz*dHy + alpha*(dEx - ndotdE*nx); + *fluxEy = nz*dHx - nx*dHz + alpha*(dEy - ndotdE*ny); + *fluxEz = nx*dHy - ny*dHx + alpha*(dEz - ndotdE*nz); +} + +// batch process elements +@kernel void maxwellSurfaceTet3D(const dlong Nelements, + @restrict const dlong * elementIds, + @restrict const dfloat * sgeo, + @restrict const dfloat * LIFT, + @restrict const dlong * vmapM, + @restrict const dlong * vmapP, + @restrict const int * EToB, + const dfloat time, + @restrict const dfloat * x, + @restrict const dfloat * y, + @restrict const dfloat * z, + @restrict const dfloat * q, + @restrict dfloat * rhsq){ + + // for all elements + for(dlong eo=0;eo0){ + maxwellDirichletConditions3D(bc, time, x[idM], y[idM], z[idM], nx, ny, nz, HxM, HyM, HzM, ExM, EyM, EzM, &HxP, &HyP, &HzP, &ExP, &EyP, &EzP); + } + + // evaluate "flux" terms: (sJ/J)*(A*nx+B*ny)*(q^* - q^-) + const dfloat sc = p_half*invJ*sJ; + + dfloat fluxHx, fluxHy, fluxHz; + dfloat fluxEx, fluxEy, fluxEz; + + upwind(nx, ny, nz, HxM, HyM, HzM, ExM, EyM, EzM, HxP, HyP, HzP, ExP, EyP, EzP, &fluxHx, &fluxHy, &fluxHz, &fluxEx, &fluxEy, &fluxEz); + + s_fluxHx[es][n] = sc*(fluxHx); + s_fluxHy[es][n] = sc*(fluxHy); + s_fluxHz[es][n] = sc*(fluxHz); + s_fluxEx[es][n] = sc*(fluxEx); + s_fluxEy[es][n] = sc*(fluxEy); + s_fluxEz[es][n] = sc*(fluxEz); + } + } + } + } + + // for each node in the element + for(int es=0;es0){ + maxwellDirichletConditions2D(bc, time, x[idM], y[idM], nx, ny, HxM, HyM, EzM, &HxP, &HyP, &EzP); + //should also add the Neumann BC here, but need uxM, uyM, vxM, abd vyM somehow + } + + // evaluate "flux" terms: (sJ/J)*(A*nx+B*ny)*(q^* - q^-) + const dfloat sc = invJ*sJ; + + dfloat fluxHx, fluxHy, fluxEz; + + upwind(nx, ny, HxM, HyM, EzM, HxP, HyP, EzP, &fluxHx, &fluxHy, &fluxEz); + + // const dfloat hinv = sgeo[sid + p_IHID]; + // dfloat penalty = p_Nq*p_Nq*hinv*mu; + + s_fluxHx[es][n] = sc*(fluxHx); + s_fluxHy[es][n] = sc*(fluxHy); + s_fluxEz[es][n] = sc*(fluxEz); + } + } + } + } + + // for each node in the element + for(int es=0;es Q, const std::string fileName){ + + FILE *fp; + + fp = fopen(fileName.c_str(), "w"); + + fprintf(fp, "\n"); + fprintf(fp, " \n"); + fprintf(fp, " \n", + mesh.Nelements*mesh.plotNp, + mesh.Nelements*mesh.plotNelements); + + // write out nodes + fprintf(fp, " \n"); + fprintf(fp, " \n"); + + //scratch space for interpolation + size_t Nscratch = std::max(mesh.Np, mesh.plotNp); + memory scratch(2*Nscratch); + + memory Ix(mesh.plotNp); + memory Iy(mesh.plotNp); + memory Iz(mesh.plotNp); + + // compute plot node coordinates on the fly + for(dlong e=0;e\n"); + fprintf(fp, " \n"); + + memory IHx(mesh.plotNp); + memory IHy(mesh.plotNp); + memory IHz(mesh.plotNp); + + // write out magnetic field + fprintf(fp, " \n"); + fprintf(fp, " \n", mesh.dim); + for(dlong e=0;e\n"); + + memory IEx(mesh.plotNp); + memory IEy(mesh.plotNp); + memory IEz(mesh.plotNp); + + // write out electric field + if(mesh.dim==2){ + fprintf(fp, " \n", 1); + }else{ + fprintf(fp, " \n", mesh.dim); + } + + for(dlong e=0;e\n"); + fprintf(fp, " \n"); + + + fprintf(fp, " \n"); + fprintf(fp, " \n"); + + for(dlong e=0;e\n"); + + fprintf(fp, " \n"); + dlong cnt = 0; + for(dlong e=0;e\n"); + + fprintf(fp, " \n"); + for(dlong e=0;e\n"); + fprintf(fp, " \n"); + fprintf(fp, " \n"); + fprintf(fp, " \n"); + fprintf(fp, "\n"); + fclose(fp); +} diff --git a/solvers/maxwell/src/maxwellReport.cpp b/solvers/maxwell/src/maxwellReport.cpp new file mode 100644 index 000000000..13d2c21a5 --- /dev/null +++ b/solvers/maxwell/src/maxwellReport.cpp @@ -0,0 +1,69 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "maxwell.hpp" + +void maxwell_t::Report(dfloat time, int tstep){ + + static int frame=0; + dfloat L2error = 0; + + if (settings.compareSetting("COMPUTE ERROR","TRUE")) { + deviceMemory o_err = platform.reserve(mesh.Nelements); + // only set up for Tri and Tet elements + errorKernel(mesh.Nelements, time, mesh.o_vgeo, mesh.o_x, mesh.o_y, mesh.o_z, mesh.o_MM, o_q, o_err); + L2error = sqrt(platform.linAlg().sum(mesh.Nelements, o_err, mesh.comm)); + } + + //compute q.M*q + dlong Nentries = mesh.Nelements*mesh.Np*Nfields; + deviceMemory o_Mq = platform.reserve(Nentries); + mesh.MassMatrixApply(o_q, o_Mq); + + dfloat norm2 = sqrt(platform.linAlg().innerProd(Nentries, o_q, o_Mq, mesh.comm)); + + if(mesh.rank==0) { + if (settings.compareSetting("COMPUTE ERROR","TRUE")) { + printf("%5.2f (%d), %5.2f, %5.2e (time, timestep, norm, L2error)\n", time, tstep, norm2, L2error); + } else { + printf("%5.2f (%d), %5.2f (time, timestep, norm)\n", time, tstep, norm2); + } + } + + if (settings.compareSetting("OUTPUT TO FILE","TRUE")) { + + // copy data back to host + o_q.copyTo(q); + + // output field files + std::string name; + settings.getSetting("OUTPUT FILE NAME", name); + char fname[BUFSIZ]; + sprintf(fname, "%s_%04d_%04d.vtu", name.c_str(), mesh.rank, frame++); + + PlotFields(q, std::string(fname)); + } +} diff --git a/solvers/maxwell/src/maxwellRun.cpp b/solvers/maxwell/src/maxwellRun.cpp new file mode 100644 index 000000000..e37ae6263 --- /dev/null +++ b/solvers/maxwell/src/maxwellRun.cpp @@ -0,0 +1,66 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "maxwell.hpp" + +void maxwell_t::Run(){ + + dfloat startTime, finalTime; + settings.getSetting("START TIME", startTime); + settings.getSetting("FINAL TIME", finalTime); + + initialConditionKernel(mesh.Nelements, + startTime, + mesh.o_x, + mesh.o_y, + mesh.o_z, + o_q); + + dfloat cfl=1.0; + settings.getSetting("CFL NUMBER", cfl); + + // set time step + dfloat hmin = mesh.MinCharacteristicLength(); + dfloat vmax = MaxWaveSpeed(); + + dfloat dt = cfl*hmin/(vmax*(mesh.N+1.)*(mesh.N+1.)); + timeStepper.SetTimeStep(dt); + + timeStepper.Run(*this, o_q, startTime, finalTime); + + // output norm of final solution + { + //compute q.M*q + dlong Nentries = mesh.Nelements*mesh.Np*Nfields; + deviceMemory o_Mq = platform.reserve(Nentries); + mesh.MassMatrixApply(o_q, o_Mq); + + dfloat norm2 = sqrt(platform.linAlg().innerProd(Nentries, o_q, o_Mq, mesh.comm)); + + if(mesh.rank==0) + printf("Solution norm = %17.15lg\n", norm2); + } +} diff --git a/solvers/maxwell/src/maxwellSettings.cpp b/solvers/maxwell/src/maxwellSettings.cpp new file mode 100644 index 000000000..d9938894b --- /dev/null +++ b/solvers/maxwell/src/maxwellSettings.cpp @@ -0,0 +1,109 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "maxwell.hpp" + +//settings for maxwell solver +maxwellSettings_t::maxwellSettings_t(comm_t _comm): + settings_t(_comm) { + + newSetting("DATA FILE", + "data/maxwellGaussian2D.h", + "Boundary and Initial conditions header"); + + newSetting("TIME INTEGRATOR", + "DOPRI5", + "Time integration method", + {"AB3", "DOPRI5", "LSERK4"}); + + newSetting("CFL NUMBER", + "1.0", + "Multiplier for timestep stability bound"); + + newSetting("START TIME", + "0", + "Start time for time integration"); + + newSetting("FINAL TIME", + "10", + "End time for time integration"); + + newSetting("OUTPUT INTERVAL", + ".1", + "Time between printing output data"); + + newSetting("OUTPUT TO FILE", + "FALSE", + "Flag for writing fields to VTU files", + {"TRUE", "FALSE"}); + + newSetting("OUTPUT FILE NAME", + "maxwell"); + + newSetting("COMPUTE ERROR", + "FALSE", + "Flag for computing L2 error (uses InitialCondition from data file)", + {"TRUE", "FALSE"}); + +} + +void maxwellSettings_t::report() { + + if (comm.rank()==0) { + std::cout << "Maxwell Settings:\n\n"; + reportSetting("DATA FILE"); + reportSetting("TIME INTEGRATOR"); + reportSetting("START TIME"); + reportSetting("FINAL TIME"); + reportSetting("OUTPUT INTERVAL"); + reportSetting("OUTPUT TO FILE"); + reportSetting("OUTPUT FILE NAME"); + reportSetting("COMPUTE ERROR"); + } +} + +void maxwellSettings_t::parseFromFile(platformSettings_t& platformSettings, + meshSettings_t& meshSettings, + const std::string filename) { + //read all settings from file + settings_t s(comm); + s.readSettingsFromFile(filename); + + for(auto it = s.settings.begin(); it != s.settings.end(); ++it) { + setting_t& set = it->second; + const std::string name = set.getName(); + const std::string val = set.getVal(); + if (platformSettings.hasSetting(name)) + platformSettings.changeSetting(name, val); + else if (meshSettings.hasSetting(name)) + meshSettings.changeSetting(name, val); + else if (hasSetting(name)) //self + changeSetting(name, val); + else { + LIBP_FORCE_ABORT("Unknown setting: [" << name << "] requested"); + } + } +} diff --git a/solvers/maxwell/src/maxwellSetup.cpp b/solvers/maxwell/src/maxwellSetup.cpp new file mode 100644 index 000000000..d830d874c --- /dev/null +++ b/solvers/maxwell/src/maxwellSetup.cpp @@ -0,0 +1,139 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "maxwell.hpp" + +void maxwell_t::Setup(platform_t& _platform, mesh_t& _mesh, + maxwellSettings_t& _settings){ + + platform = _platform; + mesh = _mesh; + comm = _mesh.comm; + settings = _settings; + + Nfields = (mesh.dim==3) ? 6:3; + + dlong Nlocal = mesh.Nelements*mesh.Np*Nfields; + dlong Nhalo = mesh.totalHaloPairs*mesh.Np*Nfields; + + //Trigger JIT kernel builds + ogs::InitializeKernels(platform, ogs::Dfloat, ogs::Add); + + //setup linear algebra module + platform.linAlg().InitKernels({"innerProd", "sum", "norm2"}); + + /*setup trace halo exchange */ + traceHalo = mesh.HaloTraceSetup(Nfields); + + //setup timeStepper + if (settings.compareSetting("TIME INTEGRATOR","AB3")){ + timeStepper.Setup(mesh.Nelements, + mesh.totalHaloPairs, + mesh.Np, Nfields, platform, comm); + } else if (settings.compareSetting("TIME INTEGRATOR","LSERK4")){ + timeStepper.Setup(mesh.Nelements, + mesh.totalHaloPairs, + mesh.Np, Nfields, platform, comm); + } else if (settings.compareSetting("TIME INTEGRATOR","DOPRI5")){ + timeStepper.Setup(mesh.Nelements, + mesh.totalHaloPairs, + mesh.Np, Nfields, platform, comm); + } + + // set penalty parameter + dfloat Lambda2 = 0.5; + + // compute samples of q at interpolation nodes + q.malloc(Nlocal+Nhalo); + o_q = platform.malloc(Nlocal+Nhalo); + + mesh.MassMatrixKernelSetup(Nfields); // mass matrix operator + + // OCCA build stuff + properties_t kernelInfo = mesh.props; //copy base occa properties + + //add boundary data to kernel info + std::string dataFileName; + settings.getSetting("DATA FILE", dataFileName); + kernelInfo["includes"] += dataFileName; + + kernelInfo["defines/" "p_Nfields"]= Nfields; + + const dfloat p_half = 1./2.; + kernelInfo["defines/" "p_half"]= p_half; + + int maxNodes = std::max(mesh.Np, (mesh.Nfp*mesh.Nfaces)); + kernelInfo["defines/" "p_maxNodes"]= maxNodes; + + int blockMax = 256; + if (platform.device.mode() == "CUDA") blockMax = 512; + + int NblockV = std::max(1, blockMax/mesh.Np); + kernelInfo["defines/" "p_NblockV"]= NblockV; + + int NblockS = std::max(1, blockMax/maxNodes); + kernelInfo["defines/" "p_NblockS"]= NblockS; + + kernelInfo["defines/" "p_Lambda2"]= Lambda2; + + // set kernel name suffix + std::string suffix = mesh.elementSuffix(); + std::string oklFilePrefix = DMAXWELL "/okl/"; + std::string oklFileSuffix = ".okl"; + + std::string fileName, kernelName; + + // kernels from volume file + fileName = oklFilePrefix + "maxwellVolume" + suffix + oklFileSuffix; + kernelName = "maxwellVolume" + suffix; + + volumeKernel = platform.buildKernel(fileName, kernelName, + kernelInfo); + // kernels from surface file + fileName = oklFilePrefix + "maxwellSurface" + suffix + oklFileSuffix; + kernelName = "maxwellSurface" + suffix; + + surfaceKernel = platform.buildKernel(fileName, kernelName, + kernelInfo); + + // kernels from surface file + fileName = oklFilePrefix + "maxwellError" + suffix + oklFileSuffix; + kernelName = "maxwellError" + suffix; + + errorKernel = platform.buildKernel(fileName, kernelName, + kernelInfo); + + if (mesh.dim==2) { + fileName = oklFilePrefix + "maxwellInitialCondition2D" + oklFileSuffix; + kernelName = "maxwellInitialCondition2D"; + } else { + fileName = oklFilePrefix + "maxwellInitialCondition3D" + oklFileSuffix; + kernelName = "maxwellInitialCondition3D"; + } + + initialConditionKernel = platform.buildKernel(fileName, kernelName, + kernelInfo); +} diff --git a/solvers/maxwell/src/maxwellStep.cpp b/solvers/maxwell/src/maxwellStep.cpp new file mode 100644 index 000000000..5c7262797 --- /dev/null +++ b/solvers/maxwell/src/maxwellStep.cpp @@ -0,0 +1,78 @@ +/* + +The MIT License (MIT) + +Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "maxwell.hpp" + +dfloat maxwell_t::MaxWaveSpeed(){ + //wavespeed is constant 1 everywhere + const dfloat vmax = 1.0; + return vmax; +} + +//evaluate ODE rhs = f(q,t) +void maxwell_t::rhsf(deviceMemory& o_Q, deviceMemory& o_RHS, const dfloat T){ + + // extract q halo on DEVICE + traceHalo.ExchangeStart(o_Q, 1); + + volumeKernel(mesh.Nelements, + mesh.o_vgeo, + mesh.o_D, + o_Q, + o_RHS); + + if (mesh.NinternalElements) + surfaceKernel(mesh.NinternalElements, + mesh.o_internalElementIds, + mesh.o_sgeo, + mesh.o_LIFT, + mesh.o_vmapM, + mesh.o_vmapP, + mesh.o_EToB, + T, + mesh.o_x, + mesh.o_y, + mesh.o_z, + o_Q, + o_RHS); + + traceHalo.ExchangeFinish(o_Q, 1); + + if (mesh.NhaloElements) + surfaceKernel(mesh.NhaloElements, + mesh.o_haloElementIds, + mesh.o_sgeo, + mesh.o_LIFT, + mesh.o_vmapM, + mesh.o_vmapP, + mesh.o_EToB, + T, + mesh.o_x, + mesh.o_y, + mesh.o_z, + o_Q, + o_RHS); +} diff --git a/test/makefile b/test/makefile index 2e2b3da30..6b3dc5d6d 100644 --- a/test/makefile +++ b/test/makefile @@ -45,7 +45,7 @@ Can use "make verbose=true" for verbose output. endef -ifeq (,$(filter info help test test-mesh test-gradient test-advection test-acoustics \ +ifeq (,$(filter info help test test-mesh test-gradient test-advection test-acoustics test-maxwell \ test-elliptic test-fpe test-cns test-bns test-lbs test-ins test-initial-guess test-core,$(MAKECMDGOALS))) ifneq (,$(MAKECMDGOALS)) $(error ${TEST_HELP_MSG}) @@ -68,7 +68,7 @@ MESH_DIR =${LIBP_LIBS_DIR}/mesh CORE_DIR =${LIBP_DIR}/core TEST_DIR =${LIBP_DIR}/test -.PHONY: all help info test test-mesh test-gradient test-advection test-acoustics \ +.PHONY: all help info test test-mesh test-gradient test-advection test-acoustics test-maxwell \ test-elliptic test-fpe test-cns test-bns test-ins test-initial-guess test-core @@ -119,6 +119,9 @@ test-bns: test-lbs: @./testLbs.py +test-maxwell: + @./testMaxwell.py + test-ins: @./testIns.py diff --git a/test/test.py b/test/test.py index f182435c8..0ba3df9e9 100755 --- a/test/test.py +++ b/test/test.py @@ -47,6 +47,7 @@ bnsDir = solverDir + "/bns" lbsDir = solverDir + "/lbs" insDir = solverDir + "/ins" +maxwellDir = solverDir + "/maxwell" gradientBin = gradientDir + "/gradientMain" advectionBin = advectionDir + "/advectionMain" @@ -57,6 +58,7 @@ bnsBin = bnsDir + "/bnsMain" lbsBin = lbsDir + "/lbsMain" insBin = insDir + "/insMain" +maxwellBin = maxwellDir + "/maxwellMain" inputRC = testDir + "/setup.rc" @@ -164,6 +166,7 @@ def test(name, cmd, settings, referenceNorm, ranks=1): import testMesh import testGradient import testAdvection + import testMaxwell import testAcoustics import testElliptic import testFokkerPlanck @@ -182,6 +185,7 @@ def test(name, cmd, settings, referenceNorm, ranks=1): failCount+=testParAdogs.main() failCount+=testGradient.main() failCount+=testAdvection.main() + failCount+=testMaxwell.main() failCount+=testAcoustics.main() failCount+=testElliptic.main() failCount+=testFokkerPlanck.main() @@ -194,4 +198,5 @@ def test(name, cmd, settings, referenceNorm, ranks=1): failCount+=testLinearSolver.main() failCount+=testParAlmond.main() + sys.exit(failCount) diff --git a/test/testMaxwell.py b/test/testMaxwell.py new file mode 100755 index 000000000..8668fee48 --- /dev/null +++ b/test/testMaxwell.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +##################################################################################### +# +#The MIT License (MIT) +# +#Copyright (c) 2017-2022 Tim Warburton, Noel Chalmers, Jesse Chan, Ali Karakus +# +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. +# +##################################################################################### + +from test import * + +data2D = maxwellDir + "/data/maxwellGaussian2D.h" +data3D = maxwellDir + "/data/maxwellGaussian3D.h" + +def maxwellSettings(rcformat="2.0", data_file=data2D, + mesh="BOX", dim=2, element=4, nx=10, ny=10, nz=10, boundary_flag=-1, + degree=4, thread_model=device, platform_number=0, device_number=0, + time_integrator="DOPRI5", cfl=1.0, start_time=0.0, final_time=1.0, + output_to_file="FALSE"): + return [setting_t("FORMAT", rcformat), + setting_t("DATA FILE", data_file), + setting_t("MESH FILE", mesh), + setting_t("MESH DIMENSION", dim), + setting_t("ELEMENT TYPE", element), + setting_t("BOX GLOBAL NX", nx), + setting_t("BOX GLOBAL NY", ny), + setting_t("BOX GLOBAL NZ", nz), + setting_t("BOX BOUNDARY FLAG", boundary_flag), + setting_t("POLYNOMIAL DEGREE", degree), + setting_t("THREAD MODEL", thread_model), + setting_t("PLATFORM NUMBER", platform_number), + setting_t("DEVICE NUMBER", device_number), + setting_t("TIME INTEGRATOR", time_integrator), + setting_t("CFL NUMBER", cfl), + setting_t("START TIME", start_time), + setting_t("FINAL TIME", final_time), + setting_t("OUTPUT TO FILE", output_to_file)] + +def main(): + failCount=0; + + failCount += test(name="testMaxwellTri", + cmd=maxwellBin, + settings=maxwellSettings(element=3,data_file=data2D,dim=2), + referenceNorm=0.723919093728707) + + failCount += test(name="testMaxwellTet", + cmd=maxwellBin, + settings=maxwellSettings(element=6,data_file=data3D,dim=3, + degree=2), + referenceNorm=0.494395985627954) + + failCount += test(name="testMaxwellTri_MPI", ranks=4, + cmd=maxwellBin, + settings=maxwellSettings(element=3,data_file=data2D,dim=2,output_to_file="TRUE"), + referenceNorm=0.723919093728707) + + #clean up + for file_name in os.listdir(testDir): + if file_name.endswith('.vtu'): + os.remove(testDir + "/" + file_name) + + return failCount + +if __name__ == "__main__": + failCount=0; + failCount+=main() + sys.exit(failCount)