mirror of
https://codeberg.org/vcbferreira/NuFI_deal.ii
synced 2026-08-12 14:33:18 +02:00
Merge branch 'refinement_tree_locator' into 1x2v
# Conflicts: # Makefile # README.md # cmake_install.cmake # libnufi_lib.a # nufi/fields.h # nufi/parameters.h # nufi/save_results.h # src/nufi_solver.cc # src/save_results.cc
This commit is contained in:
+6
-5
@@ -1,10 +1,11 @@
|
|||||||
.ipynb_checkpoints/
|
build/
|
||||||
CMakeCache.txt
|
|
||||||
compile_commands.json
|
|
||||||
CMakeFiles/
|
|
||||||
results/
|
results/
|
||||||
|
|
||||||
saved_sims/
|
saved_sims/
|
||||||
nufi_poisson
|
|
||||||
|
.ipynb_checkpoints/
|
||||||
*.ipynb
|
*.ipynb
|
||||||
|
|
||||||
.todo-txt/
|
.todo-txt/
|
||||||
Notes/
|
Notes/
|
||||||
|
|||||||
@@ -1,271 +0,0 @@
|
|||||||
# CMAKE generated file: DO NOT EDIT!
|
|
||||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.18
|
|
||||||
|
|
||||||
# Default target executed when no arguments are given to make.
|
|
||||||
default_target: all
|
|
||||||
|
|
||||||
.PHONY : default_target
|
|
||||||
|
|
||||||
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
|
|
||||||
.NOTPARALLEL:
|
|
||||||
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Special targets provided by cmake.
|
|
||||||
|
|
||||||
# Disable implicit rules so canonical targets will work.
|
|
||||||
.SUFFIXES:
|
|
||||||
|
|
||||||
|
|
||||||
# Disable VCS-based implicit rules.
|
|
||||||
% : %,v
|
|
||||||
|
|
||||||
|
|
||||||
# Disable VCS-based implicit rules.
|
|
||||||
% : RCS/%
|
|
||||||
|
|
||||||
|
|
||||||
# Disable VCS-based implicit rules.
|
|
||||||
% : RCS/%,v
|
|
||||||
|
|
||||||
|
|
||||||
# Disable VCS-based implicit rules.
|
|
||||||
% : SCCS/s.%
|
|
||||||
|
|
||||||
|
|
||||||
# Disable VCS-based implicit rules.
|
|
||||||
% : s.%
|
|
||||||
|
|
||||||
|
|
||||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
|
||||||
|
|
||||||
|
|
||||||
# Command-line flag to silence nested $(MAKE).
|
|
||||||
$(VERBOSE)MAKESILENT = -s
|
|
||||||
|
|
||||||
#Suppress display of executed commands.
|
|
||||||
$(VERBOSE).SILENT:
|
|
||||||
|
|
||||||
# A target that is always out of date.
|
|
||||||
cmake_force:
|
|
||||||
|
|
||||||
.PHONY : cmake_force
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Set environment variables for the build.
|
|
||||||
|
|
||||||
# The shell in which to execute make rules.
|
|
||||||
SHELL = /bin/sh
|
|
||||||
|
|
||||||
# The CMake executable.
|
|
||||||
CMAKE_COMMAND = /usr/local/bin/cmake
|
|
||||||
|
|
||||||
# The command to remove a file.
|
|
||||||
RM = /usr/local/bin/cmake -E rm -f
|
|
||||||
|
|
||||||
# Escaping for special characters.
|
|
||||||
EQUALS = =
|
|
||||||
|
|
||||||
# The top-level source directory on which CMake was run.
|
|
||||||
CMAKE_SOURCE_DIR = /home/vf/Thesis/dealII_NuFI
|
|
||||||
|
|
||||||
# The top-level build directory on which CMake was run.
|
|
||||||
CMAKE_BINARY_DIR = /home/vf/Thesis/dealII_NuFI
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Targets provided globally by CMake.
|
|
||||||
|
|
||||||
# Special rule for the target rebuild_cache
|
|
||||||
rebuild_cache:
|
|
||||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
|
|
||||||
/usr/local/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
|
||||||
.PHONY : rebuild_cache
|
|
||||||
|
|
||||||
# Special rule for the target rebuild_cache
|
|
||||||
rebuild_cache/fast: rebuild_cache
|
|
||||||
|
|
||||||
.PHONY : rebuild_cache/fast
|
|
||||||
|
|
||||||
# Special rule for the target edit_cache
|
|
||||||
edit_cache:
|
|
||||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
|
|
||||||
/usr/local/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
|
||||||
.PHONY : edit_cache
|
|
||||||
|
|
||||||
# Special rule for the target edit_cache
|
|
||||||
edit_cache/fast: edit_cache
|
|
||||||
|
|
||||||
.PHONY : edit_cache/fast
|
|
||||||
|
|
||||||
# The main all target
|
|
||||||
all: cmake_check_build_system
|
|
||||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/vf/Thesis/dealII_NuFI/CMakeFiles /home/vf/Thesis/dealII_NuFI//CMakeFiles/progress.marks
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
|
|
||||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/vf/Thesis/dealII_NuFI/CMakeFiles 0
|
|
||||||
.PHONY : all
|
|
||||||
|
|
||||||
# The main clean target
|
|
||||||
clean:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean
|
|
||||||
.PHONY : clean
|
|
||||||
|
|
||||||
# The main clean target
|
|
||||||
clean/fast: clean
|
|
||||||
|
|
||||||
.PHONY : clean/fast
|
|
||||||
|
|
||||||
# Prepare targets for installation.
|
|
||||||
preinstall: all
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
|
|
||||||
.PHONY : preinstall
|
|
||||||
|
|
||||||
# Prepare targets for installation.
|
|
||||||
preinstall/fast:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
|
|
||||||
.PHONY : preinstall/fast
|
|
||||||
|
|
||||||
# clear depends
|
|
||||||
depend:
|
|
||||||
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
|
|
||||||
.PHONY : depend
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Target rules for targets named nufi_poisson
|
|
||||||
|
|
||||||
# Build rule for target.
|
|
||||||
nufi_poisson: cmake_check_build_system
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 nufi_poisson
|
|
||||||
.PHONY : nufi_poisson
|
|
||||||
|
|
||||||
# fast build rule for target.
|
|
||||||
nufi_poisson/fast:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_poisson.dir/build.make CMakeFiles/nufi_poisson.dir/build
|
|
||||||
.PHONY : nufi_poisson/fast
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Target rules for targets named nufi_lib
|
|
||||||
|
|
||||||
# Build rule for target.
|
|
||||||
nufi_lib: cmake_check_build_system
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 nufi_lib
|
|
||||||
.PHONY : nufi_lib
|
|
||||||
|
|
||||||
# fast build rule for target.
|
|
||||||
nufi_lib/fast:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/build
|
|
||||||
.PHONY : nufi_lib/fast
|
|
||||||
|
|
||||||
src/main.o: src/main.cc.o
|
|
||||||
|
|
||||||
.PHONY : src/main.o
|
|
||||||
|
|
||||||
# target to build an object file
|
|
||||||
src/main.cc.o:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_poisson.dir/build.make CMakeFiles/nufi_poisson.dir/src/main.cc.o
|
|
||||||
.PHONY : src/main.cc.o
|
|
||||||
|
|
||||||
src/main.i: src/main.cc.i
|
|
||||||
|
|
||||||
.PHONY : src/main.i
|
|
||||||
|
|
||||||
# target to preprocess a source file
|
|
||||||
src/main.cc.i:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_poisson.dir/build.make CMakeFiles/nufi_poisson.dir/src/main.cc.i
|
|
||||||
.PHONY : src/main.cc.i
|
|
||||||
|
|
||||||
src/main.s: src/main.cc.s
|
|
||||||
|
|
||||||
.PHONY : src/main.s
|
|
||||||
|
|
||||||
# target to generate assembly for a file
|
|
||||||
src/main.cc.s:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_poisson.dir/build.make CMakeFiles/nufi_poisson.dir/src/main.cc.s
|
|
||||||
.PHONY : src/main.cc.s
|
|
||||||
|
|
||||||
src/nufi_solver.o: src/nufi_solver.cc.o
|
|
||||||
|
|
||||||
.PHONY : src/nufi_solver.o
|
|
||||||
|
|
||||||
# target to build an object file
|
|
||||||
src/nufi_solver.cc.o:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/src/nufi_solver.cc.o
|
|
||||||
.PHONY : src/nufi_solver.cc.o
|
|
||||||
|
|
||||||
src/nufi_solver.i: src/nufi_solver.cc.i
|
|
||||||
|
|
||||||
.PHONY : src/nufi_solver.i
|
|
||||||
|
|
||||||
# target to preprocess a source file
|
|
||||||
src/nufi_solver.cc.i:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/src/nufi_solver.cc.i
|
|
||||||
.PHONY : src/nufi_solver.cc.i
|
|
||||||
|
|
||||||
src/nufi_solver.s: src/nufi_solver.cc.s
|
|
||||||
|
|
||||||
.PHONY : src/nufi_solver.s
|
|
||||||
|
|
||||||
# target to generate assembly for a file
|
|
||||||
src/nufi_solver.cc.s:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/src/nufi_solver.cc.s
|
|
||||||
.PHONY : src/nufi_solver.cc.s
|
|
||||||
|
|
||||||
src/save_results.o: src/save_results.cc.o
|
|
||||||
|
|
||||||
.PHONY : src/save_results.o
|
|
||||||
|
|
||||||
# target to build an object file
|
|
||||||
src/save_results.cc.o:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/src/save_results.cc.o
|
|
||||||
.PHONY : src/save_results.cc.o
|
|
||||||
|
|
||||||
src/save_results.i: src/save_results.cc.i
|
|
||||||
|
|
||||||
.PHONY : src/save_results.i
|
|
||||||
|
|
||||||
# target to preprocess a source file
|
|
||||||
src/save_results.cc.i:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/src/save_results.cc.i
|
|
||||||
.PHONY : src/save_results.cc.i
|
|
||||||
|
|
||||||
src/save_results.s: src/save_results.cc.s
|
|
||||||
|
|
||||||
.PHONY : src/save_results.s
|
|
||||||
|
|
||||||
# target to generate assembly for a file
|
|
||||||
src/save_results.cc.s:
|
|
||||||
$(MAKE) $(MAKESILENT) -f CMakeFiles/nufi_lib.dir/build.make CMakeFiles/nufi_lib.dir/src/save_results.cc.s
|
|
||||||
.PHONY : src/save_results.cc.s
|
|
||||||
|
|
||||||
# Help Target
|
|
||||||
help:
|
|
||||||
@echo "The following are some of the valid targets for this Makefile:"
|
|
||||||
@echo "... all (the default if no target is provided)"
|
|
||||||
@echo "... clean"
|
|
||||||
@echo "... depend"
|
|
||||||
@echo "... edit_cache"
|
|
||||||
@echo "... rebuild_cache"
|
|
||||||
@echo "... nufi_lib"
|
|
||||||
@echo "... nufi_poisson"
|
|
||||||
@echo "... src/main.o"
|
|
||||||
@echo "... src/main.i"
|
|
||||||
@echo "... src/main.s"
|
|
||||||
@echo "... src/nufi_solver.o"
|
|
||||||
@echo "... src/nufi_solver.i"
|
|
||||||
@echo "... src/nufi_solver.s"
|
|
||||||
@echo "... src/save_results.o"
|
|
||||||
@echo "... src/save_results.i"
|
|
||||||
@echo "... src/save_results.s"
|
|
||||||
.PHONY : help
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Special targets to cleanup operation of make.
|
|
||||||
|
|
||||||
# Special rule to run CMake to check the build system integrity.
|
|
||||||
# No rule that depends on this can have commands that come from listfiles
|
|
||||||
# because they might be regenerated.
|
|
||||||
cmake_check_build_system:
|
|
||||||
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
|
|
||||||
.PHONY : cmake_check_build_system
|
|
||||||
|
|
||||||
@@ -1,14 +1,28 @@
|
|||||||
# Vlasov-Poisson model solver
|
# Vlasov-Poisson model solver
|
||||||
|
|
||||||
This simulation of the Vlasov-Poisson system dimensions uses
|
This simulation of the Vlasov-Poisson system dimensions uses
|
||||||
|
|
||||||
- [NuFI algorithm](https://doi.org/10.1002/pamm.202300162)
|
- [NuFI algorithm](https://doi.org/10.1002/pamm.202300162)
|
||||||
- [deal.ii](https://dealii.org/) FEM package
|
- [deal.ii](https://dealii.org/) FEM package
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
dimensions: 1x2v
|
|
||||||
|
|
||||||
status: working, needs testing, not optimized (at all!)
|
dimensions: 1x1v
|
||||||
|
|
||||||
|
notes:
|
||||||
|
|
||||||
|
- Locator not optimized for 1d.
|
||||||
|
- works for higher dimensions
|
||||||
|
- locator up to O(dim * Max_depth)
|
||||||
|
-
|
||||||
|
|
||||||
|
status: Working
|
||||||
|
|
||||||
Refinement working:
|
Refinement working:
|
||||||
|
|
||||||
- grid versions saved on a vector
|
- grid versions saved on a vector
|
||||||
- solutions point to a version of the grid
|
- solutions point to a version of the grid
|
||||||
|
|
||||||
|
todo:
|
||||||
|
|
||||||
|
- add ions
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
# Install script for directory: /home/vf/Thesis/dealII_NuFI
|
|
||||||
|
|
||||||
# Set the install prefix
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "/usr/local")
|
|
||||||
endif()
|
|
||||||
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
|
|
||||||
# Set the install configuration name.
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
|
||||||
if(BUILD_TYPE)
|
|
||||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
|
||||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
|
||||||
endif()
|
|
||||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set the component getting installed.
|
|
||||||
if(NOT CMAKE_INSTALL_COMPONENT)
|
|
||||||
if(COMPONENT)
|
|
||||||
message(STATUS "Install component: \"${COMPONENT}\"")
|
|
||||||
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_COMPONENT)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Install shared libraries without execute permission?
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
|
||||||
set(CMAKE_INSTALL_SO_NO_EXE "1")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Is this installation the result of a crosscompile?
|
|
||||||
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
|
||||||
set(CMAKE_CROSSCOMPILING "FALSE")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set default install directory permissions.
|
|
||||||
if(NOT DEFINED CMAKE_OBJDUMP)
|
|
||||||
set(CMAKE_OBJDUMP "/usr/bin/objdump")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_INSTALL_COMPONENT)
|
|
||||||
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
|
|
||||||
"${CMAKE_INSTALL_MANIFEST_FILES}")
|
|
||||||
file(WRITE "/home/vf/Thesis/dealII_NuFI/${CMAKE_INSTALL_MANIFEST}"
|
|
||||||
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
|
|
||||||
Binary file not shown.
+95
-66
@@ -1,117 +1,146 @@
|
|||||||
#ifndef CELLS_H
|
#ifndef CELLS_H
|
||||||
#define CELLS_H
|
#define CELLS_H
|
||||||
|
|
||||||
#include <algorithm>
|
#include <array>
|
||||||
#include <boost/geometry/geometries/concepts/point_concept.hpp>
|
#include <cmath>
|
||||||
#include <deal.II/base/geometry_info.h>
|
#include <deal.II/base/geometry_info.h>
|
||||||
#include <deal.II/base/point.h>
|
#include <deal.II/base/point.h>
|
||||||
#include <deal.II/dofs/dof_handler.h>
|
#include <deal.II/dofs/dof_handler.h>
|
||||||
#include <deal.II/fe/mapping_q.h>
|
|
||||||
#include <deal.II/grid/tria.h>
|
#include <deal.II/grid/tria.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "nufi/parameters.h"
|
||||||
|
|
||||||
using namespace dealii;
|
using namespace dealii;
|
||||||
|
|
||||||
template <int dim> struct CellInfo {
|
|
||||||
// what needs to be given to evaluator
|
|
||||||
typename DoFHandler<dim>::active_cell_iterator cell;
|
|
||||||
// usefull for locator
|
|
||||||
Point<dim> lower;
|
|
||||||
Point<dim> upper;
|
|
||||||
double h;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int dim> struct CellLocation {
|
template <int dim> struct CellLocation {
|
||||||
const CellInfo<dim> *info;
|
typename DoFHandler<dim>::active_cell_iterator cell;
|
||||||
Point<dim> reference_point;
|
Point<dim> reference_point;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int dim> class CellLocator {
|
template <int dim> class CellLocator {
|
||||||
public:
|
public:
|
||||||
using CellIterator = typename DoFHandler<dim>::active_cell_iterator;
|
|
||||||
|
|
||||||
void rebuild(const DoFHandler<dim> &dof_handler,
|
void rebuild(const DoFHandler<dim> &dof_handler,
|
||||||
const Triangulation<dim> &triangulation);
|
const Triangulation<dim> &triangulation);
|
||||||
|
|
||||||
CellLocation<dim> locate(const Point<dim> &p) const;
|
CellLocation<dim> locate(const Point<dim> &p) const;
|
||||||
|
|
||||||
const std::vector<Point<dim>> &get_cell_centers() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CellInfo<dim>> cells;
|
const DoFHandler<dim> *dof_handler_ptr = nullptr;
|
||||||
std::vector<Point<dim>> cell_centers;
|
Point<dim> lower;
|
||||||
|
Point<dim> upper;
|
||||||
|
|
||||||
|
// Cached base level = Parameters::GLOBAL_REFINEMENT.
|
||||||
|
unsigned int base_level = 0;
|
||||||
|
unsigned int base_n_per_axis = 1; // 2^base_level
|
||||||
|
|
||||||
|
std::vector<typename Triangulation<dim>::cell_iterator> base_cells;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int dim>
|
template <int dim>
|
||||||
void CellLocator<dim>::rebuild(const DoFHandler<dim> &dof_handler,
|
void CellLocator<dim>::rebuild(const DoFHandler<dim> &dof_handler,
|
||||||
const Triangulation<dim> &triangulation) {
|
const Triangulation<dim> &triangulation) {
|
||||||
|
dof_handler_ptr = &dof_handler;
|
||||||
|
|
||||||
cells.clear();
|
AssertThrow(triangulation.n_cells(0) == 1,
|
||||||
cells.reserve(triangulation.n_active_cells());
|
ExcMessage("CellLocator assumes exactly one coarse/root cell."));
|
||||||
|
|
||||||
for (const auto &cell : dof_handler.active_cell_iterators()) {
|
typename Triangulation<dim>::cell_iterator root = triangulation.begin(0);
|
||||||
CellInfo<dim> info;
|
lower = root->vertex(0);
|
||||||
|
upper = root->vertex(GeometryInfo<dim>::vertices_per_cell - 1);
|
||||||
|
|
||||||
info.cell = cell;
|
base_level = Parameters::GLOBAL_REFINEMENT;
|
||||||
info.lower = cell->vertex(0);
|
base_n_per_axis = 1u << base_level; // = 2^base_level
|
||||||
info.upper = cell->vertex(GeometryInfo<dim>::vertices_per_cell - 1);
|
|
||||||
|
|
||||||
info.h = info.upper[0] - info.lower[0];
|
const unsigned int n_base_cells =
|
||||||
|
1u << (dim * base_level); // = 2^(dim*base_level)
|
||||||
|
base_cells.assign(n_base_cells, typename Triangulation<dim>::cell_iterator());
|
||||||
|
|
||||||
cells.push_back(info);
|
std::vector<typename Triangulation<dim>::cell_iterator> stack;
|
||||||
|
std::vector<unsigned int> index_stack;
|
||||||
|
std::vector<unsigned int> depth_stack;
|
||||||
|
stack.push_back(root);
|
||||||
|
index_stack.push_back(0);
|
||||||
|
depth_stack.push_back(0);
|
||||||
|
|
||||||
|
while (!stack.empty()) {
|
||||||
|
auto cell = stack.back();
|
||||||
|
unsigned int idx = index_stack.back();
|
||||||
|
unsigned int depth = depth_stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
index_stack.pop_back();
|
||||||
|
depth_stack.pop_back();
|
||||||
|
|
||||||
|
if (depth == base_level) {
|
||||||
|
base_cells[idx] = cell;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(cells.begin(), cells.end(),
|
AssertThrow(cell->has_children(),
|
||||||
[](const CellInfo<dim> &a, const CellInfo<dim> &b) {
|
ExcMessage("CellLocator: mesh is not uniformly refined to "
|
||||||
return a.lower[0] < b.lower[0];
|
"Parameters::GLOBAL_REFINEMENT; base-level cache "
|
||||||
});
|
"cannot be built. Did you coarsen below the "
|
||||||
|
"global refinement level?"));
|
||||||
|
|
||||||
cell_centers.clear();
|
const unsigned int n_children = GeometryInfo<dim>::max_children_per_cell;
|
||||||
cell_centers.reserve(cells.size());
|
for (unsigned int c = 0; c < n_children; ++c) {
|
||||||
|
stack.push_back(cell->child(c));
|
||||||
for (const auto &cell : cells) {
|
index_stack.push_back(idx * n_children + c);
|
||||||
Point<dim> center;
|
depth_stack.push_back(depth + 1);
|
||||||
for (unsigned int d = 0; d < dim; ++d)
|
}
|
||||||
center[d] = 0.5 * (cell.lower[d] + cell.upper[d]);
|
|
||||||
|
|
||||||
cell_centers.push_back(center);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int dim>
|
template <int dim>
|
||||||
CellLocation<dim> CellLocator<dim>::locate(const Point<dim> &p) const {
|
CellLocation<dim> CellLocator<dim>::locate(const Point<dim> &p) const {
|
||||||
static_assert(dim == 1,
|
AssertThrow(dof_handler_ptr != nullptr,
|
||||||
"Current CellLocator implementation only supports 1D.");
|
|
||||||
|
|
||||||
AssertThrow(!cells.empty(),
|
|
||||||
ExcMessage("CellLocator::rebuild() has not been called."));
|
ExcMessage("CellLocator::rebuild() has not been called."));
|
||||||
|
|
||||||
const double x = p[0];
|
Point<dim> p_wrapped;
|
||||||
|
for (unsigned int d = 0; d < dim; ++d) {
|
||||||
|
const double L = upper[d] - lower[d];
|
||||||
|
double x = p[d] - lower[d];
|
||||||
|
x = x - L * std::floor(x / L);
|
||||||
|
p_wrapped[d] = lower[d] + x;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = std::upper_bound(cells.begin(), cells.end(), x,
|
Point<dim> xi;
|
||||||
[](double value, const CellInfo<dim> &cell) {
|
for (unsigned int d = 0; d < dim; ++d) {
|
||||||
return value < cell.lower[0];
|
xi[d] = (p_wrapped[d] - lower[d]) / (upper[d] - lower[d]);
|
||||||
}); // returns cell to the right of cell with x
|
xi[d] = std::min(std::max(xi[d], 0.0), 1.0); // of cell at base level
|
||||||
|
}
|
||||||
|
|
||||||
if (it == cells.begin())
|
unsigned int idx = 0;
|
||||||
it = cells.begin();
|
Point<dim> xi_local = xi;
|
||||||
else
|
for (unsigned int l = 0; l < base_level; ++l) {
|
||||||
--it;
|
const unsigned int child_index =
|
||||||
|
GeometryInfo<dim>::child_cell_from_point(xi_local);
|
||||||
|
xi_local =
|
||||||
|
GeometryInfo<dim>::cell_to_child_coordinates(xi_local, child_index);
|
||||||
|
idx = idx * GeometryInfo<dim>::max_children_per_cell + child_index;
|
||||||
|
}
|
||||||
|
|
||||||
// Safety check: make sure the point is really inside this cell
|
typename Triangulation<dim>::cell_iterator cell = base_cells[idx];
|
||||||
AssertThrow(x >= it->lower[0] - 1e-12 && x <= it->upper[0] + 1e-12,
|
xi = xi_local;
|
||||||
ExcMessage("CellLocator failed to find containing cell."));
|
|
||||||
|
// Step 4: continue descending only through ADAPTIVE refinement beyond
|
||||||
|
// the base level -- this loop now only runs `depth - base_level` times
|
||||||
|
// instead of `depth` times.
|
||||||
|
while (cell->has_children()) {
|
||||||
|
const unsigned int child_index =
|
||||||
|
GeometryInfo<dim>::child_cell_from_point(xi);
|
||||||
|
xi = GeometryInfo<dim>::cell_to_child_coordinates(xi, child_index);
|
||||||
|
cell = cell->child(child_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
typename DoFHandler<dim>::active_cell_iterator dof_cell(
|
||||||
|
&cell->get_triangulation(), cell->level(), cell->index(),
|
||||||
|
dof_handler_ptr);
|
||||||
|
|
||||||
CellLocation<dim> location;
|
CellLocation<dim> location;
|
||||||
|
location.cell = dof_cell;
|
||||||
location.info = &(*it);
|
location.reference_point = xi;
|
||||||
location.reference_point[0] = (p[0] - it->lower[0]) / it->h;
|
|
||||||
|
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int dim>
|
|
||||||
const std::vector<Point<dim>> &CellLocator<dim>::get_cell_centers() const {
|
|
||||||
return cell_centers;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !CELLS_H
|
#endif // !CELLS_H
|
||||||
|
|||||||
+76
-34
@@ -1,9 +1,9 @@
|
|||||||
#ifndef FIELDS_H
|
#ifndef NUFI_FIELDS_H_
|
||||||
#define FIELDS_H
|
#define NUFI_FIELDS_H_
|
||||||
|
|
||||||
#include "nufi/grids.h"
|
#include "nufi/grids.h"
|
||||||
#include "nufi/parameters.h"
|
#include "nufi/parameters.h"
|
||||||
#include "nufi/poisson_problem.h"
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <deal.II/base/function.h>
|
#include <deal.II/base/function.h>
|
||||||
@@ -13,25 +13,76 @@
|
|||||||
using namespace dealii;
|
using namespace dealii;
|
||||||
|
|
||||||
inline std::vector<double> make_x_eval(size_t Nx) {
|
inline std::vector<double> make_x_eval(size_t Nx) {
|
||||||
|
|
||||||
std::vector<double> x_eval_E;
|
std::vector<double> x_eval_E;
|
||||||
|
|
||||||
double dx = (Parameters::X_DOMAIN_RIGHT - Parameters::X_DOMAIN_LEFT) / Nx;
|
double dx = (Parameters::X_DOMAIN_RIGHT - Parameters::X_DOMAIN_LEFT) / Nx;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < Nx; ++i) {
|
for (unsigned int i = 0; i < Nx; ++i)
|
||||||
x_eval_E.push_back(Parameters::X_DOMAIN_LEFT + (i + 0.5) * dx);
|
x_eval_E.push_back(Parameters::X_DOMAIN_LEFT + (i + 0.5) * dx);
|
||||||
}
|
|
||||||
return x_eval_E;
|
return x_eval_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double f0(const double x, const double v1, const double v2,
|
inline void reset_x_eval(std::vector<double> &x_vals) {
|
||||||
const double eps = Parameters::EPS,
|
const size_t Nx = x_vals.size();
|
||||||
const double k = Parameters::WAVE_NR) {
|
const double dx = Parameters::LX / Nx;
|
||||||
const double prefactor =
|
for (size_t i = 0; i < Nx; ++i)
|
||||||
Parameters::F0_FACTOR * (1.0 + eps * std::cos(k * x));
|
x_vals[i] = Parameters::X_DOMAIN_LEFT + i * dx;
|
||||||
const double gaussian = v1 * v1 * std::exp(-0.5 * (v1 * v1 + v2 * v2));
|
};
|
||||||
|
|
||||||
return prefactor * gaussian;
|
inline double f0(const double x, const double v,
|
||||||
|
const size_t f0_type = Parameters::f0_TYPE) {
|
||||||
|
const double eps = Parameters::EPS;
|
||||||
|
const double k = Parameters::WAVE_NR;
|
||||||
|
|
||||||
|
const double factor = Parameters::F0_FACTOR;
|
||||||
|
|
||||||
|
auto maxwell = [factor](double u, double v = 0, double v_th = 1) {
|
||||||
|
return 1 / v_th * factor *
|
||||||
|
std::exp(-0.5 * (u - v) * (u - v) / (v_th * v_th));
|
||||||
|
};
|
||||||
|
|
||||||
|
double prefactor;
|
||||||
|
double computed_max;
|
||||||
|
double result;
|
||||||
|
|
||||||
|
switch (f0_type) {
|
||||||
|
case 0: // two-stream
|
||||||
|
{
|
||||||
|
computed_max = maxwell(v);
|
||||||
|
prefactor = (1.0 + eps * std::cos(k * x)) * v * v;
|
||||||
|
result = prefactor * computed_max;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: // Landau-damping
|
||||||
|
{
|
||||||
|
computed_max = maxwell(v);
|
||||||
|
prefactor = (1.0 + eps * std::cos(k * x));
|
||||||
|
result = prefactor * computed_max;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: // Maxwellian
|
||||||
|
{
|
||||||
|
result = maxwell(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: // Bump-on tail
|
||||||
|
{
|
||||||
|
const double beam_density = 0.05;
|
||||||
|
const double beam_v_th = 0.2;
|
||||||
|
const double beam_v = 3;
|
||||||
|
const double alpha = beam_density / (1 - beam_density);
|
||||||
|
|
||||||
|
const double beam_max = maxwell(v, beam_v, beam_v_th);
|
||||||
|
computed_max = maxwell(v);
|
||||||
|
result = (1 - alpha) * computed_max + alpha * beam_max;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("Invalid f0_type");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrapper for eval_point() { VectorTools::point_values() }
|
// wrapper for eval_point() { VectorTools::point_values() }
|
||||||
@@ -42,50 +93,41 @@ inline std::vector<double> eval(std::vector<double> &X,
|
|||||||
AssertThrow(grid.dof_handler->n_dofs() == solution.size(),
|
AssertThrow(grid.dof_handler->n_dofs() == solution.size(),
|
||||||
ExcMessage("@ eval(...) grid's number of DoFs doesn't correspond "
|
ExcMessage("@ eval(...) grid's number of DoFs doesn't correspond "
|
||||||
"to solution's size"));
|
"to solution's size"));
|
||||||
size_t x_size = X.size();
|
|
||||||
std::vector<Point<1>> Points(x_size);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < x_size; ++i) {
|
const size_t x_size = X.size();
|
||||||
X[i] = X[i] - Parameters::X_DOMAIN_LEFT;
|
std::vector<Point<1>> points(x_size);
|
||||||
X[i] = X[i] - Parameters::LX * std::floor(X[i] * Parameters::LX_INV);
|
|
||||||
|
|
||||||
Points[i][0] = X[i];
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
}
|
points[i][0] = X[i];
|
||||||
|
|
||||||
return grid.eval_vector_grad(solution, Points);
|
return grid.eval_vector_grad(solution, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double integral_space_vector(const GridStructure<1> &grid,
|
inline double integral_space_vector(const GridStructure<1> &grid,
|
||||||
const Vector<double> &solution,
|
const Vector<double> &solution,
|
||||||
double dx = Parameters::PLOT_DX,
|
|
||||||
size_t Nx = Parameters::PLOT_NX) {
|
size_t Nx = Parameters::PLOT_NX) {
|
||||||
double integral = 0.0;
|
double integral = 0.0;
|
||||||
double xmin = Parameters::X_DOMAIN_LEFT;
|
std::vector<double> x_eval = make_x_eval(Nx);
|
||||||
std::vector<double> x_eval(Nx);
|
const double dx = Parameters::LX / Nx;
|
||||||
for (size_t i = 0; i < Nx; ++i)
|
|
||||||
x_eval[i] = xmin + i * dx;
|
|
||||||
|
|
||||||
std::vector<double> tmp = eval(x_eval, grid, solution);
|
std::vector<double> tmp = eval(x_eval, grid, solution);
|
||||||
for (size_t i = 0; i < Nx; ++i)
|
for (size_t i = 0; i < Nx; ++i)
|
||||||
integral += tmp[i];
|
integral += tmp[i];
|
||||||
return integral * dx;
|
return integral * dx;
|
||||||
};
|
}
|
||||||
|
|
||||||
inline double integral_space_vector_squared(const GridStructure<1> &grid,
|
inline double integral_space_vector_squared(const GridStructure<1> &grid,
|
||||||
const Vector<double> &solution,
|
const Vector<double> &solution,
|
||||||
double dx = Parameters::PLOT_DX,
|
|
||||||
size_t Nx = Parameters::PLOT_NX) {
|
size_t Nx = Parameters::PLOT_NX) {
|
||||||
double integral = 0.0;
|
double integral = 0.0;
|
||||||
double xmin = Parameters::X_DOMAIN_LEFT;
|
std::vector<double> x_eval = make_x_eval(Nx);
|
||||||
std::vector<double> x_eval(Nx);
|
const double dx = Parameters::LX / Nx;
|
||||||
for (size_t i = 0; i < Nx; ++i)
|
|
||||||
x_eval[i] = xmin + i * dx;
|
|
||||||
|
|
||||||
std::vector<double> tmp = eval(x_eval, grid, solution);
|
std::vector<double> tmp = eval(x_eval, grid, solution);
|
||||||
for (size_t i = 0; i < Nx; ++i)
|
for (size_t i = 0; i < Nx; ++i)
|
||||||
integral += tmp[i] * tmp[i];
|
integral += tmp[i] * tmp[i];
|
||||||
return integral * dx;
|
return integral * dx;
|
||||||
};
|
}
|
||||||
|
|
||||||
inline std::vector<double>
|
inline std::vector<double>
|
||||||
Point_vector_to_double_vector(const std::vector<Point<1>> &Points) {
|
Point_vector_to_double_vector(const std::vector<Point<1>> &Points) {
|
||||||
@@ -97,4 +139,4 @@ Point_vector_to_double_vector(const std::vector<Point<1>> &Points) {
|
|||||||
|
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // NUFI_FIELDS_H_
|
||||||
|
|||||||
+3
-3
@@ -72,12 +72,12 @@ template <int dim> struct GridStructure {
|
|||||||
|
|
||||||
const auto cell_location = locator->locate(points[p]);
|
const auto cell_location = locator->locate(points[p]);
|
||||||
|
|
||||||
cell_location.info->cell->get_dof_values(solution,
|
cell_location.cell->get_dof_values(solution,
|
||||||
local_solution_buffer.begin(),
|
local_solution_buffer.begin(),
|
||||||
local_solution_buffer.end());
|
local_solution_buffer.end());
|
||||||
|
|
||||||
evaluator.reinit(
|
evaluator.reinit(
|
||||||
cell_location.info->cell,
|
cell_location.cell,
|
||||||
ArrayView<const Point<dim>>(&cell_location.reference_point, 1));
|
ArrayView<const Point<dim>>(&cell_location.reference_point, 1));
|
||||||
|
|
||||||
evaluator.evaluate(local_solution_buffer, EvaluationFlags::gradients);
|
evaluator.evaluate(local_solution_buffer, EvaluationFlags::gradients);
|
||||||
@@ -127,7 +127,7 @@ GridStructure<dim> make_grid_snapshot(PoissonProblem<dim> &poisson) {
|
|||||||
|
|
||||||
if (PRINT_GAUGE_DOF_POSITION)
|
if (PRINT_GAUGE_DOF_POSITION)
|
||||||
std::cout << " gauge_dof = " << gauge_dof
|
std::cout << " gauge_dof = " << gauge_dof
|
||||||
<< " gauge_point = " << point[0] << std::endl;
|
<< " gauge_point = " << point[0] << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-11
@@ -2,6 +2,7 @@
|
|||||||
#define PARAMETERS_H
|
#define PARAMETERS_H
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -16,23 +17,30 @@ constexpr double LX_INV = 1 / LX;
|
|||||||
constexpr size_t CALC_NX = 256;
|
constexpr size_t CALC_NX = 256;
|
||||||
constexpr double CALC_DX = LX / CALC_NX;
|
constexpr double CALC_DX = LX / CALC_NX;
|
||||||
|
|
||||||
constexpr double V_DOMAIN_LEFT_1 = -10.;
|
constexpr double V_DOMAIN_LEFT = -10.;
|
||||||
constexpr double V_DOMAIN_RIGHT_1 = 10.;
|
constexpr double V_DOMAIN_RIGHT = 10.;
|
||||||
|
|
||||||
constexpr unsigned int NV_1 = 128;
|
constexpr unsigned int NV = 128;
|
||||||
constexpr double DV_1 = std::abs(V_DOMAIN_RIGHT_1 - V_DOMAIN_LEFT_1) / NV_1;
|
constexpr double DV = std::abs(V_DOMAIN_RIGHT - V_DOMAIN_LEFT) / NV;
|
||||||
|
|
||||||
constexpr double V_DOMAIN_LEFT_2 = -10.;
|
// f0_TYPE:
|
||||||
constexpr double V_DOMAIN_RIGHT_2 = 10.;
|
// 0 -> twos-stream
|
||||||
|
// 1 -> landau-damping
|
||||||
|
// 2 -> maxwellian
|
||||||
|
// 3 -> bump-on-tail
|
||||||
|
constexpr size_t f0_TYPE = 0;
|
||||||
|
|
||||||
constexpr unsigned int NV_2 = 128;
|
|
||||||
constexpr double DV_2 = std::abs(V_DOMAIN_RIGHT_2 - V_DOMAIN_LEFT_2) / NV_2;
|
|
||||||
// deal.ii options
|
// deal.ii options
|
||||||
constexpr unsigned int GLOBAL_REFINEMENT = 6;
|
constexpr unsigned int GLOBAL_REFINEMENT = 7;
|
||||||
constexpr unsigned int FE_DEGREE = 3;
|
constexpr unsigned int FE_DEGREE = 3;
|
||||||
constexpr unsigned int CONVERGENCE_ITERATIONS = 5000;
|
constexpr unsigned int CONVERGENCE_ITERATIONS = 5000;
|
||||||
constexpr double CONVERGENCE_LIMIT = 1e-8;
|
constexpr double CONVERGENCE_LIMIT = 1e-8;
|
||||||
|
|
||||||
|
// Adaptive refinement options
|
||||||
|
constexpr unsigned int REFINE_FREQUENCY = 30;
|
||||||
|
constexpr double REFINEMENT_TOP_FRACTION = 0.8;
|
||||||
|
constexpr double REFINEMENT_BOTTOM_FRACTION = 0.1;
|
||||||
|
|
||||||
// Gauge options
|
// Gauge options
|
||||||
constexpr double GAUGE_DOMAIN_LEFT = 3.2;
|
constexpr double GAUGE_DOMAIN_LEFT = 3.2;
|
||||||
constexpr double GAUGE_DOMAIN_RIGHT = 3.8;
|
constexpr double GAUGE_DOMAIN_RIGHT = 3.8;
|
||||||
@@ -44,13 +52,11 @@ constexpr double F0_FACTOR = 0.39894228040143267793994; // 1/sqrt(2pi)
|
|||||||
// NUFI options
|
// NUFI options
|
||||||
constexpr double DT = 1. / 10.;
|
constexpr double DT = 1. / 10.;
|
||||||
constexpr unsigned int TMAX = 100;
|
constexpr unsigned int TMAX = 100;
|
||||||
constexpr unsigned int REFINE_FREQUENCY = 30;
|
|
||||||
|
|
||||||
// Plotting options
|
// Plotting options
|
||||||
constexpr int PLOT_FREQUENCY = 10;
|
constexpr int PLOT_FREQUENCY = 10;
|
||||||
constexpr size_t PLOT_NX = CALC_NX;
|
constexpr size_t PLOT_NX = CALC_NX;
|
||||||
constexpr double PLOT_DX = LX / PLOT_NX;
|
constexpr double PLOT_DX = LX / PLOT_NX;
|
||||||
constexpr double PLOT_FIXED_V2 = 0.;
|
|
||||||
const std::string PLOT_DIR = "results/";
|
const std::string PLOT_DIR = "results/";
|
||||||
} // namespace Parameters
|
} // namespace Parameters
|
||||||
|
|
||||||
|
|||||||
+38
-27
@@ -1,9 +1,7 @@
|
|||||||
#ifndef POISSON_PROBLEM_H
|
#ifndef POISSON_PROBLEM_H
|
||||||
#define POISSON_PROBLEM_H
|
#define POISSON_PROBLEM_H
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <deal.II/base/function.h>
|
#include <deal.II/base/function.h>
|
||||||
|
|
||||||
#include <deal.II/base/index_set.h>
|
#include <deal.II/base/index_set.h>
|
||||||
#include <deal.II/base/logstream.h>
|
#include <deal.II/base/logstream.h>
|
||||||
#include <deal.II/base/mpi_remote_point_evaluation.h>
|
#include <deal.II/base/mpi_remote_point_evaluation.h>
|
||||||
@@ -42,6 +40,7 @@
|
|||||||
#include <deal.II/numerics/solution_transfer.h>
|
#include <deal.II/numerics/solution_transfer.h>
|
||||||
#include <deal.II/numerics/vector_tools.h>
|
#include <deal.II/numerics/vector_tools.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <deal.II/numerics/vector_tools_evaluate.h>
|
#include <deal.II/numerics/vector_tools_evaluate.h>
|
||||||
#include <deal.II/numerics/vector_tools_interpolate.h>
|
#include <deal.II/numerics/vector_tools_interpolate.h>
|
||||||
#include <deal.II/numerics/vector_tools_point_gradient.h>
|
#include <deal.II/numerics/vector_tools_point_gradient.h>
|
||||||
@@ -49,6 +48,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -56,6 +56,7 @@
|
|||||||
#include "nufi/cells.h"
|
#include "nufi/cells.h"
|
||||||
#include "nufi/grids.h"
|
#include "nufi/grids.h"
|
||||||
#include "nufi/parameters.h"
|
#include "nufi/parameters.h"
|
||||||
|
#include "nufi/stopwatch.h"
|
||||||
#include "omp.h"
|
#include "omp.h"
|
||||||
|
|
||||||
void save_space_vector(const std::vector<double> &vals,
|
void save_space_vector(const std::vector<double> &vals,
|
||||||
@@ -70,7 +71,7 @@ public:
|
|||||||
PoissonProblem(unsigned int degree);
|
PoissonProblem(unsigned int degree);
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void solve_step(size_t it, std::vector<GridStructure<1>> &grid_versions,
|
double solve_step(size_t it, std::vector<GridStructure<1>> &grid_versions,
|
||||||
bool refining = false);
|
bool refining = false);
|
||||||
void coarse_and_refine_grid(size_t it);
|
void coarse_and_refine_grid(size_t it);
|
||||||
void setup_constraints(AffineConstraints<double> &constraints);
|
void setup_constraints(AffineConstraints<double> &constraints);
|
||||||
@@ -91,6 +92,7 @@ public:
|
|||||||
return constraints;
|
return constraints;
|
||||||
}
|
}
|
||||||
const CellLocator<dim> &get_locator() const { return cell_locator; }
|
const CellLocator<dim> &get_locator() const { return cell_locator; }
|
||||||
|
double get_error_estimate() const { return error_estimate; }
|
||||||
|
|
||||||
std::vector<double> sample_electric_field(double x_min, double x_max,
|
std::vector<double> sample_electric_field(double x_min, double x_max,
|
||||||
unsigned int Nx);
|
unsigned int Nx);
|
||||||
@@ -108,6 +110,7 @@ private:
|
|||||||
void setup_system();
|
void setup_system();
|
||||||
void assemble_system();
|
void assemble_system();
|
||||||
void solve(size_t it);
|
void solve(size_t it);
|
||||||
|
void estimate_error();
|
||||||
|
|
||||||
std::function<std::vector<double>(const std::vector<Point<dim>> &)>
|
std::function<std::vector<double>(const std::vector<Point<dim>> &)>
|
||||||
rhs_function;
|
rhs_function;
|
||||||
@@ -124,6 +127,7 @@ private:
|
|||||||
Vector<double> system_rhs;
|
Vector<double> system_rhs;
|
||||||
|
|
||||||
const bool PRINT_GAUGE_DOF_POSITION = true;
|
const bool PRINT_GAUGE_DOF_POSITION = true;
|
||||||
|
double error_estimate = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//====//====//
|
//====//====//
|
||||||
@@ -336,10 +340,6 @@ template <int dim> void PoissonProblem<dim>::setup_system() {
|
|||||||
|
|
||||||
// used for evaluator to avoid running it anytime there is an eval
|
// used for evaluator to avoid running it anytime there is an eval
|
||||||
cell_locator.rebuild(dof_handler, triangulation);
|
cell_locator.rebuild(dof_handler, triangulation);
|
||||||
|
|
||||||
// local_solution_buffer.resize(fe.n_dofs_per_cell());
|
|
||||||
// evaluator = std::make_unique<FEPointEvaluation<dim, dim>>(mapping, fe,
|
|
||||||
// update_gradients);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int dim> void PoissonProblem<dim>::assemble_system() {
|
template <int dim> void PoissonProblem<dim>::assemble_system() {
|
||||||
@@ -375,7 +375,9 @@ template <int dim> void PoissonProblem<dim>::assemble_system() {
|
|||||||
Assert(rhs_function,
|
Assert(rhs_function,
|
||||||
ExcMessage("Poisson RHS function has not been initialized."));
|
ExcMessage("Poisson RHS function has not been initialized."));
|
||||||
|
|
||||||
|
std::cout << "Start of full rho eval..." << "\n";
|
||||||
std::vector<double> all_rho = rhs_function(all_q_points);
|
std::vector<double> all_rho = rhs_function(all_q_points);
|
||||||
|
std::cout << "End of full rho eval..." << "\n";
|
||||||
|
|
||||||
Assert(all_rho.size() == all_q_points.size(),
|
Assert(all_rho.size() == all_q_points.size(),
|
||||||
ExcMessage("rhs_function returned wrong size"));
|
ExcMessage("rhs_function returned wrong size"));
|
||||||
@@ -417,21 +419,20 @@ template <int dim> void PoissonProblem<dim>::coarse_and_refine_grid(size_t it) {
|
|||||||
dof_handler, QGauss<dim - 1>(fe.degree + 1),
|
dof_handler, QGauss<dim - 1>(fe.degree + 1),
|
||||||
std::map<types::boundary_id, const Function<dim> *>(), solution,
|
std::map<types::boundary_id, const Function<dim> *>(), solution,
|
||||||
error_per_cell);
|
error_per_cell);
|
||||||
GridRefinement::refine_and_coarsen_fixed_number(triangulation, error_per_cell,
|
|
||||||
0.3, 0.03);
|
|
||||||
|
|
||||||
// START: remove refinment flags from edges of domain to alow safe gauge
|
// GridRefinement::refine_and_coarsen_fixed_number(triangulation,
|
||||||
// fixing
|
// error_per_cell,
|
||||||
// for (const auto &cell : triangulation.active_cell_iterators()) {
|
// 0.3, 0.03);
|
||||||
// const double x = cell->center()[0];
|
GridRefinement::refine_and_coarsen_fixed_fraction(
|
||||||
// if (x >= Parameters::X_DOMAIN_RIGHT - .5) {
|
triangulation, error_per_cell, Parameters::REFINEMENT_TOP_FRACTION,
|
||||||
// cell->clear_refine_flag();
|
Parameters::REFINEMENT_BOTTOM_FRACTION,
|
||||||
// cell->clear_coarsen_flag();
|
std::numeric_limits<unsigned int>::max(), VectorTools::L2_norm);
|
||||||
// }
|
|
||||||
// }
|
// Avoid coarsing below GLOBAL_REFINEMENT level for CellLocator
|
||||||
// END
|
for (const auto &cell : triangulation.active_cell_iterators())
|
||||||
|
if (cell->level() <= static_cast<int>(Parameters::GLOBAL_REFINEMENT))
|
||||||
|
cell->clear_coarsen_flag();
|
||||||
|
|
||||||
// triangulation.prepare_coarsening_and_refinement();
|
|
||||||
triangulation.execute_coarsening_and_refinement();
|
triangulation.execute_coarsening_and_refinement();
|
||||||
|
|
||||||
std::cout << "Refinement Finished..." << "\n";
|
std::cout << "Refinement Finished..." << "\n";
|
||||||
@@ -439,13 +440,17 @@ template <int dim> void PoissonProblem<dim>::coarse_and_refine_grid(size_t it) {
|
|||||||
std::string grid_file_name =
|
std::string grid_file_name =
|
||||||
Parameters::PLOT_DIR + "grid_" + std::to_string(it);
|
Parameters::PLOT_DIR + "grid_" + std::to_string(it);
|
||||||
save_grid_to_file(grid_file_name);
|
save_grid_to_file(grid_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
// std::vector<double> Ex =
|
template <int dim> void PoissonProblem<dim>::estimate_error() {
|
||||||
// sample_electric_potential(Parameters::X_DOMAIN_LEFT,
|
Vector<float> error_per_cell(triangulation.n_active_cells());
|
||||||
// Parameters::X_DOMAIN_RIGHT,
|
|
||||||
// Parameters::PLOT_NX);
|
KellyErrorEstimator<dim>::estimate(
|
||||||
//
|
dof_handler, QGauss<dim - 1>(fe.degree + 1),
|
||||||
// save_space_vector(Ex, "Ex_after_coarsed", it);
|
std::map<types::boundary_id, const Function<dim> *>(), solution,
|
||||||
|
error_per_cell);
|
||||||
|
|
||||||
|
error_estimate = error_per_cell.l2_norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int dim> void PoissonProblem<dim>::solve(size_t it) {
|
template <int dim> void PoissonProblem<dim>::solve(size_t it) {
|
||||||
@@ -488,15 +493,21 @@ template <int dim> void PoissonProblem<dim>::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int dim>
|
template <int dim>
|
||||||
void PoissonProblem<dim>::solve_step(
|
double PoissonProblem<dim>::solve_step(
|
||||||
size_t it, std::vector<GridStructure<1>> &grid_versions, bool refining) {
|
size_t it, std::vector<GridStructure<1>> &grid_versions, bool refining) {
|
||||||
|
double refining_time = 0.0;
|
||||||
if (refining) {
|
if (refining) {
|
||||||
|
stopwatch<double> refining_timer;
|
||||||
coarse_and_refine_grid(it);
|
coarse_and_refine_grid(it);
|
||||||
setup_system();
|
setup_system();
|
||||||
update_grid_versions(grid_versions, *this);
|
update_grid_versions(grid_versions, *this);
|
||||||
|
refining_time = refining_timer.elapsed();
|
||||||
}
|
}
|
||||||
assemble_system();
|
assemble_system();
|
||||||
solve(it);
|
solve(it);
|
||||||
|
estimate_error();
|
||||||
|
|
||||||
|
return refining_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NuFI doesnt use this, kept only for testing PoissonProblem
|
// NuFI doesnt use this, kept only for testing PoissonProblem
|
||||||
|
|||||||
+19
-11
@@ -8,21 +8,29 @@
|
|||||||
|
|
||||||
class NuFISolver;
|
class NuFISolver;
|
||||||
|
|
||||||
void save_f(const NuFISolver &solver, unsigned int n, const double v2_0,
|
struct DiagnosticsSnapshot {
|
||||||
std::vector<GridStructure<1>> &grid_struct,
|
unsigned int Nx = 0;
|
||||||
std::vector<SolutionSnapshot<1>> &phi_history, unsigned int Nx_out,
|
unsigned int Nv = 0;
|
||||||
unsigned int Nv_out, const std::string &filename);
|
std::vector<double> x_eval;
|
||||||
|
std::vector<double> v_eval;
|
||||||
|
std::vector<double> f;
|
||||||
|
std::vector<double> rho;
|
||||||
|
std::vector<double> E;
|
||||||
|
};
|
||||||
|
|
||||||
void save_rho(const NuFISolver &solver, unsigned int n,
|
DiagnosticsSnapshot
|
||||||
|
compute_diagnostics(const NuFISolver &solver, unsigned int n,
|
||||||
std::vector<GridStructure<1>> &grid_struct,
|
std::vector<GridStructure<1>> &grid_struct,
|
||||||
std::vector<SolutionSnapshot<1>> &phi_history,
|
std::vector<SolutionSnapshot<1>> &phi_history,
|
||||||
unsigned int Nx_out, const std::string &filename);
|
unsigned int Nx_out, unsigned int Nv_out);
|
||||||
|
|
||||||
void save_Efield(unsigned int it, std::vector<GridStructure<1>> &grid_versions,
|
void save_f(const DiagnosticsSnapshot &snap, const std::string &filepath);
|
||||||
std::vector<SolutionSnapshot<1>> &phi_history,
|
void save_rho(const DiagnosticsSnapshot &snap, const std::string &filepath);
|
||||||
unsigned int Nx_out = Parameters::PLOT_NX);
|
void save_Efield(const DiagnosticsSnapshot &snap, const std::string &filepath);
|
||||||
|
double compute_int_E_squared(const DiagnosticsSnapshot &snap);
|
||||||
|
|
||||||
void save_space_vector(const std::vector<double> &vals,
|
void save_time_series(const std::vector<double> &t,
|
||||||
const std::string &filename, size_t it);
|
const std::vector<double> &values,
|
||||||
|
const std::string &filepath);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ void clear_results_directory(const std::string &dir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
// omp_set_max_active_levels(1);
|
||||||
std::cout << "Threads: " << omp_get_max_threads() << "\n";
|
std::cout << "Threads: " << omp_get_max_threads() << "\n";
|
||||||
try {
|
try {
|
||||||
clear_results_directory("results");
|
clear_results_directory("results");
|
||||||
|
|||||||
+88
-78
@@ -12,6 +12,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -26,18 +27,18 @@
|
|||||||
using namespace dealii;
|
using namespace dealii;
|
||||||
|
|
||||||
std::vector<double> NuFISolver::eval_ftilda(
|
std::vector<double> NuFISolver::eval_ftilda(
|
||||||
unsigned int n, std::vector<double> X, double u1, double u2,
|
unsigned int n, std::vector<double> X, double u,
|
||||||
const std::vector<GridStructure<1>> &grid_struct,
|
const std::vector<GridStructure<1>> &grid_struct,
|
||||||
const std::vector<SolutionSnapshot<1>> &phi_history) const {
|
const std::vector<SolutionSnapshot<1>> &phi_history) const {
|
||||||
|
|
||||||
size_t x_size = X.size();
|
size_t x_size = X.size();
|
||||||
|
|
||||||
std::vector<double> U1(x_size, u1);
|
std::vector<double> U(x_size, u);
|
||||||
std::vector<double> U2(x_size, u2);
|
|
||||||
std::vector<double> results(x_size);
|
std::vector<double> results(x_size);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
results[i] = f0(X[i], U1[i], U2[i]);
|
results[i] = f0(X[i], U[i]);
|
||||||
|
// reset_x_eval(X);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,53 +48,61 @@ std::vector<double> NuFISolver::eval_ftilda(
|
|||||||
// We omit the initial half-step.
|
// We omit the initial half-step.
|
||||||
while (--n) {
|
while (--n) {
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
X[i] = X[i] - Parameters::DT * U1[i];
|
X[i] = X[i] - Parameters::DT * U[i];
|
||||||
|
|
||||||
|
AssertThrow(
|
||||||
|
phi_history[n].solution.size() ==
|
||||||
|
grid_struct[phi_history[n].grid_version].dof_handler->n_dofs(),
|
||||||
|
ExcMessage("In eval_ftilda: Solution size = " +
|
||||||
|
std::to_string(phi_history[n].solution.size()) +
|
||||||
|
", expected by grid_struct = " +
|
||||||
|
std::to_string(grid_struct[phi_history[n].grid_version]
|
||||||
|
.dof_handler->n_dofs())));
|
||||||
|
AssertThrow(
|
||||||
|
grid_struct[phi_history[n].grid_version].grid_version ==
|
||||||
|
phi_history[n].grid_version,
|
||||||
|
ExcMessage(
|
||||||
|
"grid.grid_version not equal to phi_history[n].grid_version"));
|
||||||
|
|
||||||
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
||||||
phi_history[n].solution); // call eval only once
|
phi_history[n].solution); // call eval only once
|
||||||
|
|
||||||
for (size_t i = 0; i < x_size; ++i) {
|
for (size_t i = 0; i < x_size; ++i) {
|
||||||
Ex[i] = -tmp[i];
|
Ex[i] = -tmp[i];
|
||||||
U1[i] = U1[i] + Parameters::DT * Ex[i];
|
U[i] = U[i] + Parameters::DT * Ex[i];
|
||||||
|
|
||||||
// IMPORTANT!! LOOK at this before 1x2v, and check with Paul
|
|
||||||
//
|
|
||||||
// No change to U2 because dv1/dt = E_x
|
|
||||||
// but dv2/dt = E_y = 0 (because were in 1x not 2x)
|
|
||||||
// U2[i] = U2[i] + Parameters::DT * Ey[i]; TO_BUILD
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The final half-step.
|
// The final half-step.
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
X[i] = X[i] - Parameters::DT * U1[i];
|
X[i] = X[i] - Parameters::DT * U[i];
|
||||||
|
|
||||||
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
||||||
phi_history[n].solution); // call eval only once
|
phi_history[n].solution); // call eval only once
|
||||||
|
|
||||||
for (size_t i = 0; i < x_size; ++i) {
|
for (size_t i = 0; i < x_size; ++i) {
|
||||||
Ex[i] = -tmp[i];
|
Ex[i] = -tmp[i];
|
||||||
U1[i] = U1[i] + 0.5 * Parameters::DT * Ex[i];
|
U[i] = U[i] + 0.5 * Parameters::DT * Ex[i];
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
results[i] = f0(X[i], U1[i], U2[i]);
|
results[i] = f0(X[i], U[i]);
|
||||||
|
// reset_x_eval(X);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double>
|
std::vector<double>
|
||||||
NuFISolver::eval_f(unsigned int n, std::vector<double> X, double u1, double u2,
|
NuFISolver::eval_f(unsigned int n, std::vector<double> X, double u,
|
||||||
const std::vector<GridStructure<1>> &grid_struct,
|
const std::vector<GridStructure<1>> &grid_struct,
|
||||||
const std::vector<SolutionSnapshot<1>> &phi_history) const {
|
const std::vector<SolutionSnapshot<1>> &phi_history) const {
|
||||||
|
|
||||||
size_t x_size = X.size();
|
size_t x_size = X.size();
|
||||||
|
|
||||||
std::vector<double> U1(x_size, u1);
|
std::vector<double> U(x_size, u);
|
||||||
std::vector<double> U2(x_size, u2);
|
|
||||||
|
|
||||||
std::vector<double> results(x_size);
|
std::vector<double> results(x_size);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
results[i] = f0(X[i], U1[i], U2[i]);
|
results[i] = f0(X[i], U[i]);
|
||||||
|
// reset_x_eval(X);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,34 +114,35 @@ NuFISolver::eval_f(unsigned int n, std::vector<double> X, double u1, double u2,
|
|||||||
phi_history[n].solution); // call eval only once
|
phi_history[n].solution); // call eval only once
|
||||||
for (size_t i = 0; i < x_size; ++i) {
|
for (size_t i = 0; i < x_size; ++i) {
|
||||||
Ex[i] = -tmp[i];
|
Ex[i] = -tmp[i];
|
||||||
U1[i] = U1[i] + 0.5 * Parameters::DT * Ex[i];
|
U[i] = U[i] + 0.5 * Parameters::DT * Ex[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
while (--n) {
|
while (--n) {
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
X[i] = X[i] - Parameters::DT * U1[i];
|
X[i] = X[i] - Parameters::DT * U[i];
|
||||||
|
|
||||||
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
||||||
phi_history[n].solution); // call eval only once
|
phi_history[n].solution); // call eval only once
|
||||||
for (size_t i = 0; i < x_size; ++i) {
|
for (size_t i = 0; i < x_size; ++i) {
|
||||||
Ex[i] = -tmp[i];
|
Ex[i] = -tmp[i];
|
||||||
U1[i] = U1[i] + Parameters::DT * Ex[i];
|
U[i] = U[i] + Parameters::DT * Ex[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The final half-step.
|
// The final half-step.
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
X[i] = X[i] - Parameters::DT * U1[i];
|
X[i] = X[i] - Parameters::DT * U[i];
|
||||||
|
|
||||||
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
tmp = eval(X, grid_struct[phi_history[n].grid_version],
|
||||||
phi_history[n].solution); // call eval only once
|
phi_history[n].solution); // call eval only once
|
||||||
for (size_t i = 0; i < x_size; ++i) {
|
for (size_t i = 0; i < x_size; ++i) {
|
||||||
Ex[i] = -tmp[i];
|
Ex[i] = -tmp[i];
|
||||||
U1[i] = U1[i] + 0.5 * Parameters::DT * Ex[i];
|
U[i] = U[i] + 0.5 * Parameters::DT * Ex[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
results[i] = f0(X[i], U1[i], U2[i]);
|
results[i] = f0(X[i], U[i]);
|
||||||
|
// reset_x_eval(X);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,30 +150,31 @@ std::vector<double>
|
|||||||
NuFISolver::eval_rho(unsigned int n, std::vector<double> &X,
|
NuFISolver::eval_rho(unsigned int n, std::vector<double> &X,
|
||||||
const std::vector<GridStructure<1>> &grid_struct,
|
const std::vector<GridStructure<1>> &grid_struct,
|
||||||
const std::vector<SolutionSnapshot<1>> &phi_history,
|
const std::vector<SolutionSnapshot<1>> &phi_history,
|
||||||
const unsigned int Nv1, const unsigned int Nv2) const {
|
const unsigned int Nv) const {
|
||||||
size_t x_size = X.size();
|
size_t x_size = X.size();
|
||||||
|
|
||||||
const double dv_0 = Parameters::DV_1;
|
const double dv =
|
||||||
const double v_min_0 = Parameters::V_DOMAIN_LEFT_1 + 0.5 * dv_0;
|
(Parameters::V_DOMAIN_RIGHT - Parameters::V_DOMAIN_LEFT) / Nv;
|
||||||
|
const double v_min = Parameters::V_DOMAIN_LEFT + 0.5 * dv;
|
||||||
|
|
||||||
const double dv_1 = Parameters::DV_2;
|
std::vector<double> partial(static_cast<size_t>(Nv) * x_size);
|
||||||
const double v_min_1 = Parameters::V_DOMAIN_LEFT_2 + 0.5 * dv_1;
|
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (unsigned int i = 0; i < Nv; ++i) {
|
||||||
|
std::vector<double> tmp_int =
|
||||||
|
eval_ftilda(n, X, v_min + i * dv, grid_struct,
|
||||||
|
phi_history); // used eval_ftilda once per i
|
||||||
|
std::copy(tmp_int.begin(), tmp_int.end(),
|
||||||
|
partial.begin() + static_cast<size_t>(i) * x_size);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> integral(x_size, 0.0);
|
std::vector<double> integral(x_size, 0.0);
|
||||||
std::vector<double> tmp_int(x_size);
|
for (unsigned int i = 0; i < Nv; ++i)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < Nv1; ++i) {
|
|
||||||
for (unsigned int j = 0; j < Nv2; ++j) {
|
|
||||||
tmp_int =
|
|
||||||
eval_ftilda(n, X, v_min_0 + i * dv_0, v_min_1 + j * dv_1, grid_struct,
|
|
||||||
phi_history); // used eval_ftilda once per i
|
|
||||||
for (size_t ii = 0; ii < x_size; ++ii)
|
for (size_t ii = 0; ii < x_size; ++ii)
|
||||||
integral[ii] += tmp_int[ii];
|
integral[ii] += partial[static_cast<size_t>(i) * x_size + ii];
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < x_size; ++i)
|
for (size_t i = 0; i < x_size; ++i)
|
||||||
integral[i] = 1 - integral[i] * dv_0;
|
integral[i] = 1 - integral[i] * dv;
|
||||||
return integral;
|
return integral;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,11 +182,9 @@ std::vector<double>
|
|||||||
NuFISolver::eval_rho_points(unsigned int n, const std::vector<Point<1>> &points,
|
NuFISolver::eval_rho_points(unsigned int n, const std::vector<Point<1>> &points,
|
||||||
const std::vector<GridStructure<1>> &grid_struct,
|
const std::vector<GridStructure<1>> &grid_struct,
|
||||||
const std::vector<SolutionSnapshot<1>> &phi_history,
|
const std::vector<SolutionSnapshot<1>> &phi_history,
|
||||||
const unsigned int Nv1,
|
const unsigned int Nv) const {
|
||||||
const unsigned int Nv2) const {
|
|
||||||
std::vector<double> point_vector = Point_vector_to_double_vector(points);
|
std::vector<double> point_vector = Point_vector_to_double_vector(points);
|
||||||
return NuFISolver::eval_rho(n, point_vector, grid_struct, phi_history, Nv1,
|
return NuFISolver::eval_rho(n, point_vector, grid_struct, phi_history, Nv);
|
||||||
Nv2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NuFISolver::run() {
|
void NuFISolver::run() {
|
||||||
@@ -187,29 +196,20 @@ void NuFISolver::run() {
|
|||||||
using std::abs;
|
using std::abs;
|
||||||
using std::max;
|
using std::max;
|
||||||
|
|
||||||
// std::unique_ptr<double, decltype(std::free) *> rho{
|
|
||||||
// reinterpret_cast<double *>(std::aligned_alloc(64, sizeof(double) *
|
|
||||||
// Nx)),
|
|
||||||
// std::free};
|
|
||||||
//
|
|
||||||
// if (rho == nullptr)
|
|
||||||
// throw std::bad_alloc{};
|
|
||||||
|
|
||||||
std::vector<double> int_E_squared;
|
std::vector<double> int_E_squared;
|
||||||
int_E_squared.reserve(Nt);
|
int_E_squared.reserve(Nt);
|
||||||
|
std::vector<double> int_E_squared_times;
|
||||||
|
int_E_squared_times.reserve(Nt);
|
||||||
|
|
||||||
std::vector<GridStructure<1>> grid_versions;
|
std::vector<GridStructure<1>> grid_versions;
|
||||||
std::vector<SolutionSnapshot<1>> phi_history;
|
std::vector<SolutionSnapshot<1>> phi_history;
|
||||||
|
|
||||||
// update_grid_versions(grid_versions, poisson);
|
|
||||||
// update_solution_history(phi_history, poisson,
|
|
||||||
// grid_versions.back().grid_version);
|
|
||||||
|
|
||||||
std::vector<double> x_eval(Parameters::CALC_NX);
|
std::vector<double> x_eval(Parameters::CALC_NX);
|
||||||
|
|
||||||
std::ofstream time_file("results/simulation_time.dat");
|
std::ofstream time_file(Parameters::PLOT_DIR + "simulation_time.dat");
|
||||||
|
|
||||||
double total_time = 0;
|
double total_time = 0;
|
||||||
|
stopwatch<double> total_timer;
|
||||||
|
|
||||||
time_file << "it "
|
time_file << "it "
|
||||||
<< "step_time "
|
<< "step_time "
|
||||||
@@ -219,6 +219,10 @@ void NuFISolver::run() {
|
|||||||
<< "plot_time"
|
<< "plot_time"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
|
std::ofstream error_file(Parameters::PLOT_DIR + "error_estimate.dat");
|
||||||
|
error_file << "# nufi Kelly l2 error estimate\n";
|
||||||
|
error_file << "# it l2_error_estimate\n";
|
||||||
|
|
||||||
[[maybe_unused]] const double x_min = Parameters::X_DOMAIN_LEFT;
|
[[maybe_unused]] const double x_min = Parameters::X_DOMAIN_LEFT;
|
||||||
[[maybe_unused]] double dx = Parameters::CALC_DX;
|
[[maybe_unused]] double dx = Parameters::CALC_DX;
|
||||||
|
|
||||||
@@ -236,11 +240,12 @@ void NuFISolver::run() {
|
|||||||
|
|
||||||
std::cout << "Timestep " << it << " / " << Nt
|
std::cout << "Timestep " << it << " / " << Nt
|
||||||
<< " (simulation time = " << it * Parameters::DT << ")"
|
<< " (simulation time = " << it * Parameters::DT << ")"
|
||||||
<< std::endl;
|
<< "\n";
|
||||||
|
|
||||||
// START: diagnostics
|
// START: diagnostics
|
||||||
// std::cout << "cells = " << poisson.triangulation.n_active_cells() << "\n"
|
std::cout << "cells = " << poisson.get_triangulation().n_active_cells()
|
||||||
// << " dofs = " << poisson.dof_handler.n_dofs() << "\n";
|
<< "\n"
|
||||||
|
<< " dofs = " << poisson.get_dof_handler().n_dofs() << "\n";
|
||||||
// double min_h = 1e100;
|
// double min_h = 1e100;
|
||||||
// double max_h = 0;
|
// double max_h = 0;
|
||||||
//
|
//
|
||||||
@@ -276,14 +281,13 @@ void NuFISolver::run() {
|
|||||||
for (size_t i = 0; i < points.size(); ++i)
|
for (size_t i = 0; i < points.size(); ++i)
|
||||||
x[i] = points[i][0];
|
x[i] = points[i][0];
|
||||||
|
|
||||||
return eval_rho(it, x, grid_versions, phi_history, Parameters::NV_1,
|
return eval_rho(it, x, grid_versions, phi_history, Parameters::NV);
|
||||||
Parameters::NV_2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it % Parameters::REFINE_FREQUENCY == 0) {
|
if (it % Parameters::REFINE_FREQUENCY == 0) {
|
||||||
// if (it == 0) {
|
// if (it == 0) {
|
||||||
poisson.solve_step(it, grid_versions, true);
|
refine_time = poisson.solve_step(it, grid_versions, true);
|
||||||
compute_time = timer.elapsed() - compute_start;
|
compute_time = timer.elapsed() - compute_start - refine_time;
|
||||||
} else {
|
} else {
|
||||||
poisson.solve_step(it, grid_versions, false);
|
poisson.solve_step(it, grid_versions, false);
|
||||||
compute_time = timer.elapsed() - compute_start;
|
compute_time = timer.elapsed() - compute_start;
|
||||||
@@ -291,6 +295,9 @@ void NuFISolver::run() {
|
|||||||
update_solution_history(phi_history, poisson,
|
update_solution_history(phi_history, poisson,
|
||||||
grid_versions.back().grid_version);
|
grid_versions.back().grid_version);
|
||||||
|
|
||||||
|
error_file << it << " " << poisson.get_error_estimate() << "\n";
|
||||||
|
error_file.flush();
|
||||||
|
|
||||||
double timer_elapsed = timer.elapsed();
|
double timer_elapsed = timer.elapsed();
|
||||||
double step_time = timer_elapsed - time_elapsed_before;
|
double step_time = timer_elapsed - time_elapsed_before;
|
||||||
|
|
||||||
@@ -299,28 +306,31 @@ void NuFISolver::run() {
|
|||||||
//====//====//
|
//====//====//
|
||||||
// Plotting //
|
// Plotting //
|
||||||
//====//====//
|
//====//====//
|
||||||
|
|
||||||
if (it % Parameters::PLOT_FREQUENCY == 0) {
|
if (it % Parameters::PLOT_FREQUENCY == 0) {
|
||||||
double plot_start = timer.elapsed();
|
double plot_start = timer.elapsed();
|
||||||
|
|
||||||
std::cout << "Saving results... ";
|
std::cout << "Saving results... ";
|
||||||
save_f(*this, it, Parameters::PLOT_FIXED_V2, grid_versions, phi_history,
|
DiagnosticsSnapshot snap =
|
||||||
Parameters::PLOT_NX, Parameters::NV_1,
|
compute_diagnostics(*this, it, grid_versions, phi_history,
|
||||||
"results/ftilda_" + std::to_string(it) + ".dat");
|
Parameters::PLOT_NX, Parameters::NV);
|
||||||
save_rho(*this, it, grid_versions, phi_history, Parameters::PLOT_NX,
|
|
||||||
"results/rho_" + std::to_string(it) + ".dat");
|
|
||||||
|
|
||||||
save_Efield(it, grid_versions, phi_history);
|
save_f(snap, Parameters::PLOT_DIR + "f_" + std::to_string(it) + ".dat");
|
||||||
|
save_rho(snap,
|
||||||
|
Parameters::PLOT_DIR + "rho_" + std::to_string(it) + ".dat");
|
||||||
|
save_Efield(snap,
|
||||||
|
Parameters::PLOT_DIR + "E_" + std::to_string(it) + ".dat");
|
||||||
|
|
||||||
double int_val = 0.5 * integral_space_vector_squared(
|
int_E_squared.push_back(compute_int_E_squared(snap));
|
||||||
grid_versions[phi_history[it].grid_version],
|
int_E_squared_times.push_back(it * Parameters::DT);
|
||||||
phi_history[it].solution);
|
save_time_series(int_E_squared_times, int_E_squared,
|
||||||
int_E_squared.push_back(int_val);
|
Parameters::PLOT_DIR + "int_E_sqr.dat");
|
||||||
save_space_vector(int_E_squared, "electricint", it);
|
|
||||||
|
|
||||||
plot_time = timer.elapsed() - plot_start;
|
plot_time = timer.elapsed() - plot_start;
|
||||||
std::cout << "Results saved in " << plot_start << "[s]" << "\n";
|
std::cout << "Results saved in " << plot_start << "[s]" << "\n";
|
||||||
}
|
}
|
||||||
total_time = timer.elapsed();
|
|
||||||
|
total_time = total_timer.elapsed();
|
||||||
std::cout << "Time since start = " << total_time << "\n\n";
|
std::cout << "Time since start = " << total_time << "\n\n";
|
||||||
|
|
||||||
time_file << it << " " << step_time << " " << total_time << " "
|
time_file << it << " " << step_time << " " << total_time << " "
|
||||||
|
|||||||
+113
-98
@@ -4,113 +4,128 @@
|
|||||||
#include "nufi/grids.h"
|
#include "nufi/grids.h"
|
||||||
#include "nufi/nufi_solver.h"
|
#include "nufi/nufi_solver.h"
|
||||||
#include "nufi/parameters.h"
|
#include "nufi/parameters.h"
|
||||||
#include "nufi/poisson_problem.h"
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <deal.II/numerics/solution_transfer.h>
|
#include <deal.II/numerics/solution_transfer.h>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
void save_f(const NuFISolver &solver, unsigned int n, const double v2_0,
|
namespace {
|
||||||
std::vector<GridStructure<1>> &grid_struct,
|
void ensure_results_dir() { std::filesystem::create_directories("results"); }
|
||||||
std::vector<SolutionSnapshot<1>> &phi_history, unsigned int Nx_out,
|
} // namespace
|
||||||
unsigned int Nv_out, const std::string &filename) {
|
|
||||||
std::ofstream file(filename);
|
|
||||||
|
|
||||||
double xmin = Parameters::X_DOMAIN_LEFT;
|
void save_field_1d(const std::vector<double> &x,
|
||||||
double xmax = Parameters::X_DOMAIN_RIGHT;
|
const std::vector<double> &values,
|
||||||
|
const std::string &filepath) {
|
||||||
double vmin_1 = Parameters::V_DOMAIN_LEFT_1;
|
if (x.size() != values.size())
|
||||||
double vmax_1 = Parameters::V_DOMAIN_RIGHT_1;
|
throw std::runtime_error(
|
||||||
|
"save_field_1d: size mismatch (x=" + std::to_string(x.size()) +
|
||||||
double dv_1 = (vmax_1 - vmin_1) / Nv_out;
|
", values=" + std::to_string(values.size()) + ") writing " + filepath);
|
||||||
|
|
||||||
file << Nx_out << " " << Nv_out << "\n";
|
|
||||||
file << xmin << " " << xmax << "\n";
|
|
||||||
file << vmin_1 << " " << vmax_1 << "\n";
|
|
||||||
|
|
||||||
std::vector<double> x_eval = make_x_eval(Nx_out);
|
|
||||||
std::vector<double> val(Nx_out);
|
|
||||||
|
|
||||||
for (unsigned int j = 0; j < Nv_out; ++j) {
|
|
||||||
double v = vmin_1 + (j + 0.5) * dv_1;
|
|
||||||
val = solver.eval_f(n, x_eval, v, v2_0, grid_struct, phi_history);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < Nx_out; ++i) {
|
|
||||||
file << val[i];
|
|
||||||
|
|
||||||
if (i < Nx_out - 1)
|
|
||||||
file << " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
file << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_rho(const NuFISolver &solver, unsigned int n,
|
|
||||||
std::vector<GridStructure<1>> &grid_struct,
|
|
||||||
std::vector<SolutionSnapshot<1>> &phi_history,
|
|
||||||
unsigned int Nx_out, const std::string &filename) {
|
|
||||||
std::ofstream file(filename);
|
|
||||||
|
|
||||||
double xmin = Parameters::X_DOMAIN_LEFT;
|
|
||||||
double xmax = Parameters::X_DOMAIN_RIGHT;
|
|
||||||
|
|
||||||
std::vector<double> x_eval = make_x_eval(Nx_out);
|
|
||||||
file << Nx_out << "\n";
|
|
||||||
file << xmin << " " << xmax << "\n";
|
|
||||||
|
|
||||||
std::vector<double> tmp =
|
|
||||||
solver.eval_rho(n, x_eval, grid_struct, phi_history);
|
|
||||||
for (size_t i = 0; i < Nx_out; ++i) {
|
|
||||||
file << tmp[i];
|
|
||||||
file << "\n";
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_Efield(unsigned int it, std::vector<GridStructure<1>> &grid_versions,
|
|
||||||
std::vector<SolutionSnapshot<1>> &phi_history,
|
|
||||||
unsigned int Nx_out) {
|
|
||||||
std::vector<double> x_eval_E = make_x_eval(Nx_out);
|
|
||||||
|
|
||||||
auto grad_phi = eval(x_eval_E, grid_versions[phi_history[it].grid_version],
|
|
||||||
phi_history[it].solution);
|
|
||||||
|
|
||||||
std::vector<std::pair<double, double>> ordered_E;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < x_eval_E.size(); ++i) {
|
|
||||||
double E = -grad_phi[i];
|
|
||||||
ordered_E.push_back({x_eval_E[i], E});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(ordered_E.begin(), ordered_E.end());
|
|
||||||
|
|
||||||
std::ofstream E_file("results/E_" + std::to_string(it) + ".dat");
|
|
||||||
|
|
||||||
for (auto [x, E] : ordered_E)
|
|
||||||
E_file << x << " " << E << "\n";
|
|
||||||
|
|
||||||
std::cout << "Saving iteration " << it << " using grid version "
|
|
||||||
<< phi_history[it].grid_version << "\n\n";
|
|
||||||
|
|
||||||
E_file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_space_vector(const std::vector<double> &vals,
|
|
||||||
const std::string &filename, size_t it) {
|
|
||||||
std::ofstream file("results/" + filename + "_" + std::to_string(it) + ".dat");
|
|
||||||
|
|
||||||
|
ensure_results_dir();
|
||||||
|
std::ofstream file(filepath);
|
||||||
if (!file)
|
if (!file)
|
||||||
throw std::runtime_error("failed to start file in results/");
|
throw std::runtime_error("save_field_1d: failed to open " + filepath);
|
||||||
|
|
||||||
file << vals.size() << "\n";
|
file << "# nufi 1d field\n";
|
||||||
file << Parameters::X_DOMAIN_LEFT << " " << Parameters::X_DOMAIN_RIGHT
|
file << "# n = " << x.size() << "\n";
|
||||||
<< "\n";
|
file << "# columns: x value\n";
|
||||||
file << std::fixed << std::setprecision(8);
|
file << std::setprecision(10);
|
||||||
for (double val : vals)
|
for (size_t i = 0; i < x.size(); ++i)
|
||||||
file << val << "\n";
|
file << x[i] << " " << values[i] << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagnosticsSnapshot
|
||||||
|
compute_diagnostics(const NuFISolver &solver, unsigned int n,
|
||||||
|
std::vector<GridStructure<1>> &grid_struct,
|
||||||
|
std::vector<SolutionSnapshot<1>> &phi_history,
|
||||||
|
unsigned int Nx_out, unsigned int Nv_out) {
|
||||||
|
DiagnosticsSnapshot snap;
|
||||||
|
snap.Nx = Nx_out;
|
||||||
|
snap.Nv = Nv_out;
|
||||||
|
|
||||||
|
const double vmin = Parameters::V_DOMAIN_LEFT;
|
||||||
|
const double vmax = Parameters::V_DOMAIN_RIGHT;
|
||||||
|
const double dv = (vmax - vmin) / Nv_out;
|
||||||
|
|
||||||
|
snap.x_eval = make_x_eval(Nx_out);
|
||||||
|
snap.v_eval.resize(Nv_out);
|
||||||
|
for (unsigned int j = 0; j < Nv_out; ++j)
|
||||||
|
snap.v_eval[j] = vmin + (j + 0.5) * dv;
|
||||||
|
|
||||||
|
snap.f.resize(static_cast<size_t>(Nx_out) * Nv_out);
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (unsigned int j = 0; j < Nv_out; ++j) {
|
||||||
|
std::vector<double> val =
|
||||||
|
solver.eval_f(n, snap.x_eval, snap.v_eval[j], grid_struct, phi_history);
|
||||||
|
std::copy(val.begin(), val.end(), snap.f.begin() + j * Nx_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.rho.assign(Nx_out, 1.0);
|
||||||
|
for (unsigned int j = 0; j < Nv_out; ++j)
|
||||||
|
for (unsigned int i = 0; i < Nx_out; ++i)
|
||||||
|
snap.rho[i] -= snap.f[j * Nx_out + i] * dv;
|
||||||
|
|
||||||
|
std::vector<double> x_copy = snap.x_eval;
|
||||||
|
auto grad_phi = eval(x_copy, grid_struct[phi_history[n].grid_version],
|
||||||
|
phi_history[n].solution);
|
||||||
|
snap.E.resize(Nx_out);
|
||||||
|
for (unsigned int i = 0; i < Nx_out; ++i)
|
||||||
|
snap.E[i] = -grad_phi[i];
|
||||||
|
|
||||||
|
return snap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_f(const DiagnosticsSnapshot &snap, const std::string &filepath) {
|
||||||
|
ensure_results_dir();
|
||||||
|
std::ofstream file(filepath);
|
||||||
|
if (!file)
|
||||||
|
throw std::runtime_error("save_f: failed to open " + filepath);
|
||||||
|
|
||||||
|
file << "# nufi f(x,v) ascii dump\n";
|
||||||
|
file << "# Nx = " << snap.Nx << " Nv = " << snap.Nv << "\n";
|
||||||
|
file << "# columns: x v f\n";
|
||||||
|
file << std::setprecision(10);
|
||||||
|
for (unsigned int j = 0; j < snap.Nv; ++j)
|
||||||
|
for (unsigned int i = 0; i < snap.Nx; ++i)
|
||||||
|
file << snap.x_eval[i] << " " << snap.v_eval[j] << " "
|
||||||
|
<< snap.f[j * snap.Nx + i] << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_rho(const DiagnosticsSnapshot &snap, const std::string &filepath) {
|
||||||
|
save_field_1d(snap.x_eval, snap.rho, filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_Efield(const DiagnosticsSnapshot &snap, const std::string &filepath) {
|
||||||
|
save_field_1d(snap.x_eval, snap.E, filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_int_E_squared(const DiagnosticsSnapshot &snap) {
|
||||||
|
const double dx = Parameters::LX / snap.Nx;
|
||||||
|
double integral = 0.0;
|
||||||
|
for (double e : snap.E)
|
||||||
|
integral += e * e;
|
||||||
|
return 0.5 * integral * dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_time_series(const std::vector<double> &t,
|
||||||
|
const std::vector<double> &values,
|
||||||
|
const std::string &filepath) {
|
||||||
|
if (t.size() != values.size())
|
||||||
|
throw std::runtime_error(
|
||||||
|
"save_time_series: size mismatch (t=" + std::to_string(t.size()) +
|
||||||
|
", values=" + std::to_string(values.size()) + ") writing " + filepath);
|
||||||
|
|
||||||
|
ensure_results_dir();
|
||||||
|
std::ofstream file(filepath);
|
||||||
|
if (!file)
|
||||||
|
throw std::runtime_error("save_time_series: failed to open " + filepath);
|
||||||
|
|
||||||
|
file << "# nufi time series\n";
|
||||||
|
file << "# columns: t value\n";
|
||||||
|
file << std::setprecision(10);
|
||||||
|
for (size_t i = 0; i < t.size(); ++i)
|
||||||
|
file << t[i] << " " << values[i] << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user