36#ifndef PFC_BOUNDARY_CONDITIONS_MOVING_BC_HPP
37#define PFC_BOUNDARY_CONDITIONS_MOVING_BC_HPP
43#include "../field_modifier.hpp"
44#include "../utils.hpp"
52 double m_rho_low, m_rho_high;
53 double m_xwidth = 15.0;
56 double m_threshold = 0.1;
60 std::vector<double> xline, global_xline;
62 int rank = mpi::get_comm_rank(comm);
63 int size = mpi::get_comm_size(comm);
64 std::string m_name =
"MovingBC";
74 void set_xpos(
double xpos) { m_xpos =
xpos; }
75 double get_xpos()
const {
return m_xpos; }
77 void set_xwidth(
double xwidth) { m_xwidth = xwidth; }
78 double get_xwidth()
const {
return m_xwidth; }
80 void set_alpha(
double alpha) { m_alpha = alpha; }
82 void set_disp(
double disp) { m_disp =
disp; }
85 double get_threshold()
const {
return m_threshold; }
90 const FFT &fft =
m.get_fft();
91 Field &field =
m.get_real_field(get_field_name());
93 Int3
low = get_inbox(fft).low;
94 Int3
high = get_inbox(fft).high;
96 auto Lx = get_size(
w, 0);
97 auto dx = get_spacing(
w, 0);
98 auto x0 = get_origin(
w, 0);
102 if (rank == 0) global_xline.resize(
Lx);
105 fill(xline.begin(), xline.end(), std::numeric_limits<double>::min());
111 xline[
i] = std::max(xline[
i], field[
idx++]);
118 for (
int i = global_xline.size() - 1;
i >= 0;
i--) {
119 if (global_xline[
i] > m_threshold) {
125 while (global_xline[m_idx %
Lx] > m_threshold) {
141 std::cout <<
"Boundary position: " << m_xpos << std::endl;
147 const World &
w =
m.get_world();
148 const double Lx = get_size(
w, 0);
149 const double dx = get_spacing(
w, 0);
150 const double l =
Lx *
dx;
151 const double xpos = std::fmod(m_xpos,
l);
152 const double xwidth = m_xwidth;
153 const double alpha = m_alpha;
155 pfc::field::apply_inplace(
156 m, get_field_name(), [=](
const pfc::Real3 &
X,
double current) {
157 const double x =
X[0];
159 auto blend = [&](
double d) {
160 const double S = 1.0 / (1.0 + std::exp(-alpha *
d));
161 return m_rho_low *
S + m_rho_high * (1.0 -
S);
164 if (std::abs(dist) < xwidth) {
167 if (xpos < xwidth && std::abs(dist - l) < xwidth) {
168 return blend(dist - l);
170 if (xpos > l - xwidth && std::abs(dist + l) < xwidth) {
171 return blend(dist + l);
Definition field_modifier.hpp:240
The Model class represents the physics model for simulations in OpenPFC.
Definition model.hpp:95
Definition moving_bc.hpp:49
void apply(Model &m, double) override
Apply the field modification to the model (pure virtual)
Definition moving_bc.hpp:89
const std::string & get_modifier_name() const override
Get the name of the field modifier.
Definition moving_bc.hpp:87
Functional, coordinate-space field operations (header-only)
FFT class for distributed-memory parallel Fourier transforms.
Definition fft.hpp:248
Represents the global simulation domain (the "world").
Definition world.hpp:91