From ecec18f3807f0df415ec2fc706ead8a1e5ee76c3 Mon Sep 17 00:00:00 2001 From: Matteo Cicuttin <datafl4sh@toxicnet.eu> Date: Thu, 6 May 2021 18:18:47 +0200 Subject: [PATCH] Parametrizing the solver with Lua: interface conditions on CPU. --- include/maxwell_interface.h | 16 +++++++-- src/maxwell_common.cpp | 42 ++++++++++++++++++++++- src/maxwell_cpu.cpp | 68 +++++++++++++++++++++++++++++++++++-- src/maxwell_solver.cpp | 1 + 4 files changed, 121 insertions(+), 6 deletions(-) diff --git a/include/maxwell_interface.h b/include/maxwell_interface.h index 0c6a57a..27d62b4 100644 --- a/include/maxwell_interface.h +++ b/include/maxwell_interface.h @@ -34,6 +34,14 @@ enum class boundary_condition SURFACE_CURRENT }; +enum class interface_condition +{ + UNSPECIFIED, + E_FIELD, + H_FIELD, + SURFACE_CURRENT +}; + class parameter_loader : public parameter_loader_base { void init(void); @@ -54,9 +62,11 @@ public: bool initial_Hfield_defined(void) const; vec3d initial_Hfield(const point_3d&) const; - vec3d eval_plane_wave_E(int, const point_3d&, double) const; + vec3d eval_boundary_source(int, const point_3d&, double) const; + vec3d eval_interface_source(int, const point_3d&, double) const; - boundary_condition boundary_type(int tag) const; + boundary_condition boundary_type(int tag) const; + interface_condition interface_type(int tag) const; }; #endif /* HIDE_THIS_FROM_NVCC */ @@ -243,7 +253,6 @@ struct solver_state_gpu #endif /* ENABLE_GPU_SOLVER */ #ifndef HIDE_THIS_FROM_NVCC - void init_from_model(const model&, solver_state&); void init_matparams(const model&, solver_state&, const parameter_loader&); void apply_operator(solver_state&, const field&, field&); @@ -261,6 +270,7 @@ void timestep(solver_state_gpu&); void init_boundary_conditions(const model&, const parameter_loader&, vecxd&); void init_lax_milgram(const model&, const parameter_loader&, vecxd&, vecxd&, vecxd&, vecxd&); void eval_boundary_sources(const model&, const parameter_loader&, solver_state&, field&); +void eval_interface_sources(const model&, const parameter_loader&, solver_state&, field&); #endif /* HIDE_THIS_FROM_NVCC */ template<typename Function> diff --git a/src/maxwell_common.cpp b/src/maxwell_common.cpp index 7a4ff69..9f5dff7 100644 --- a/src/maxwell_common.cpp +++ b/src/maxwell_common.cpp @@ -297,8 +297,39 @@ parameter_loader::boundary_type(int tag) const return boundary_condition::UNSPECIFIED; } +interface_condition +parameter_loader::interface_type(int tag) const +{ + auto bnd_data = lua["ifaceconds"][tag]; + if (not bnd_data.valid()) + return interface_condition::UNSPECIFIED; + + auto kind = bnd_data["kind"]; + if (not kind.valid()) + { + std::cout << "[CONFIG] warning: 'kind' not specified on interface "; + std::cout << tag << std::endl; + return interface_condition::UNSPECIFIED; + } + + std::string kind_str = kind; + + if (kind_str == "E_field") + return interface_condition::E_FIELD; + + if (kind_str == "H_field") + return interface_condition::H_FIELD; + + if (kind_str == "surface_current") + return interface_condition::SURFACE_CURRENT; + + std::cout << "[CONFIG] warning: 'kind' invalid on boundary "; + std::cout << tag << std::endl; + return interface_condition::UNSPECIFIED; +} + vec3d -parameter_loader::eval_plane_wave_E(int tag, const point_3d& pt, double t) const +parameter_loader::eval_boundary_source(int tag, const point_3d& pt, double t) const { vec3d ret; sol::tie(ret(0), ret(1), ret(2)) = @@ -306,4 +337,13 @@ parameter_loader::eval_plane_wave_E(int tag, const point_3d& pt, double t) const return ret; } +vec3d +parameter_loader::eval_interface_source(int tag, const point_3d& pt, double t) const +{ + vec3d ret; + sol::tie(ret(0), ret(1), ret(2)) = + lua["ifaceconds"][tag]["source"](tag, pt.x(), pt.y(), pt.z(), t); + return ret; +} + } // namespace maxwell \ No newline at end of file diff --git a/src/maxwell_cpu.cpp b/src/maxwell_cpu.cpp index 3ce0b41..c8ffddb 100644 --- a/src/maxwell_cpu.cpp +++ b/src/maxwell_cpu.cpp @@ -80,10 +80,10 @@ eval_boundary_sources(const model& mod, const parameter_loader& mpl, case boundary_condition::PLANE_WAVE_E: { auto fE = [&](const point_3d& pt) -> vec3d { - return mpl.eval_plane_wave_E(bd.gmsh_entity, pt, state.curr_time); + return mpl.eval_boundary_source(bd.gmsh_entity, pt, state.curr_time); }; auto fH = [&](const point_3d& pt) -> vec3d { - vec3d E = mpl.eval_plane_wave_E(bd.gmsh_entity, pt, state.curr_time); + vec3d E = mpl.eval_boundary_source(bd.gmsh_entity, pt, state.curr_time); return n.cross(E)/Z; }; matxd prjE = e.project_on_face(iF, fE); @@ -116,6 +116,70 @@ eval_boundary_sources(const model& mod, const parameter_loader& mpl, } } +void +eval_interface_sources(const model& mod, const parameter_loader& mpl, + solver_state& state, field& srcfield) +{ + auto& bds = mod.boundary_descriptors(); + assert( srcfield.num_dofs == mod.num_fluxes() ); + + size_t face_num_base = 0; + for (auto& e : mod) + { + for (size_t iF = 0; iF < e.num_faces(); iF++) + { + auto& pf = e.face(iF); + auto bar = pf.barycenter(); + auto eps = mpl.epsilon(e.gmsh_tag(), bar); + auto mu = mpl.mu(e.gmsh_tag(), bar); + auto Z = std::sqrt(mu/eps); + + vec3d n = state.eds[e.number()].normals.row(iF); + + auto gfnum = face_num_base + iF; + auto bd = bds[gfnum]; + if (bd.type == face_type::NONE or bd.type == face_type::BOUNDARY) + continue; + + switch ( mpl.interface_type(bd.gmsh_entity) ) + { + case interface_condition::E_FIELD: { + /* This is BS actually... */ + auto fE = [&](const point_3d& pt) -> vec3d { + return mpl.eval_interface_source(bd.gmsh_entity, pt, state.curr_time); + }; + + matxd prjE = e.project_on_face(iF, fE); + auto num_bf = prjE.rows(); + srcfield.Ex.segment(gfnum*num_bf, num_bf) = prjE.col(0); + srcfield.Ey.segment(gfnum*num_bf, num_bf) = prjE.col(1); + srcfield.Ez.segment(gfnum*num_bf, num_bf) = prjE.col(2); + } break; + + case interface_condition::SURFACE_CURRENT: { + auto fJ = [&](const point_3d& pt) -> vec3d { + vec3d J = mpl.eval_interface_source(bd.gmsh_entity, pt, state.curr_time); + return n.cross(J); + }; + + matxd prjJ = e.project_on_face(iF, fJ); + auto num_bf = prjJ.rows(); + srcfield.Hx.segment(gfnum*num_bf, num_bf) = prjJ.col(0); + srcfield.Hy.segment(gfnum*num_bf, num_bf) = prjJ.col(1); + srcfield.Hz.segment(gfnum*num_bf, num_bf) = prjJ.col(2); + } break; + + case interface_condition::H_FIELD: + break; + + default: + break; + } + } + + face_num_base += e.num_faces(); + } +} void init_from_model(const model& mod, solver_state& state) { diff --git a/src/maxwell_solver.cpp b/src/maxwell_solver.cpp index 68e4371..5e3fdfe 100644 --- a/src/maxwell_solver.cpp +++ b/src/maxwell_solver.cpp @@ -65,6 +65,7 @@ void test_it(const model& mod, State& state, const maxwell::parameter_loader& mp for(size_t i = 0; i < num_timesteps; i++) { maxwell::eval_boundary_sources(mod, mpl, state, state.bndsrcs); + maxwell::eval_interface_sources(mod, mpl, state, state.bndsrcs); timestep(state); std::stringstream ss; ss << "maxwell_" << i << ".silo"; -- GitLab