diff --git a/python/wrap/test_features.cpp b/python/wrap/test_features.cpp index 14094389..fc0621ab 100644 --- a/python/wrap/test_features.cpp +++ b/python/wrap/test_features.cpp @@ -1,66 +1,66 @@ /** * @file * * @author Lucas Frérot <lucas.frerot@epfl.ch> * * @section LICENSE * * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "kelvin.hh" +#include "mindlin.hh" #include "model.hh" #include "model_type.hh" #include "volume_potential.hh" #include "wrap.hh" /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ namespace wrap { - -template <model_type type, UInt tensor_order> -void wrapKelvin(py::module& mod) { +template <template <model_type, UInt> class KOp, model_type type, + UInt tensor_order> +void wrapKOp(const std::string& basename, py::module& mod) { constexpr UInt dim = model_type_traits<type>::dimension; std::stringstream str; - str << "Kelvin_" << tensor_order; - py::class_<Kelvin<type, tensor_order>>(mod, str.str().c_str()) + str << basename << tensor_order; + py::class_<KOp<type, tensor_order>>(mod, str.str().c_str()) .def(py::init<Model*>()) .def("apply", - [](const Kelvin<type, tensor_order>& engine, Grid<Real, dim>& in, - Grid<Real, dim>& out) { - engine.apply(in, out); - }); + [](const KOp<type, tensor_order>& engine, Grid<Real, dim>& in, + Grid<Real, dim>& out) { engine.apply(in, out); }); } /// Wrap temporary features for testing void wrapTestFeatures(py::module& mod) { auto test_module = mod.def_submodule("_test_features"); test_module.doc() = "Module for testing new features.\n" "DISCLAIMER: this API is subject to frequent and unannounced changes " "and should **not** be relied upon!"; - wrapKelvin<model_type::volume_2d, 2>(test_module); - wrapKelvin<model_type::volume_2d, 3>(test_module); - wrapKelvin<model_type::volume_2d, 4>(test_module); + wrapKOp<Kelvin, model_type::volume_2d, 2>("Kelvin_", test_module); + wrapKOp<Kelvin, model_type::volume_2d, 3>("Kelvin_", test_module); + wrapKOp<Kelvin, model_type::volume_2d, 4>("Kelvin_", test_module); + wrapKOp<Mindlin, model_type::volume_2d, 3>("Mindlin_", test_module); } } __END_TAMAAS__ diff --git a/src/SConscript b/src/SConscript index 6fc1464c..82b287cf 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,114 +1,115 @@ import os Import('main_env') def prepend(path, list): return [os.path.join(path, x) for x in list] env = main_env # Core core_list = """ fft_plan_manager.cpp fftransform.cpp fftransform_fftw.cpp grid.cpp grid_hermitian.cpp statistics.cpp surface.cpp tamaas.cpp legacy_types.cpp loop.cpp """.split() core_list = prepend('core', core_list) core_list.append('tamaas_info.cpp') # Lib roughcontact generator_list = """ surface_generator.cpp surface_generator_filter.cpp surface_generator_filter_fft.cpp isopowerlaw.cpp """.split() generator_list = prepend('surface', generator_list) # Lib PERCOLATION percolation_list = """ flood_fill.cpp """.split() percolation_list = prepend('percolation', percolation_list) # BEM PERCOLATION bem_list = """ bem_kato.cpp bem_polonski.cpp bem_gigi.cpp bem_gigipol.cpp bem_penalty.cpp bem_uzawa.cpp bem_fft_base.cpp bem_functional.cpp bem_meta_functional.cpp elastic_energy_functional.cpp exponential_adhesion_functional.cpp squared_exponential_adhesion_functional.cpp maugis_adhesion_functional.cpp complimentary_term_functional.cpp bem_grid.cpp bem_grid_polonski.cpp bem_grid_kato.cpp bem_grid_teboulle.cpp bem_grid_condat.cpp """.split() bem_list = prepend('bem', bem_list) # Model model_list = """ model.cpp model_factory.cpp model_type.cpp model_template.cpp be_engine.cpp westergaard.cpp elastic_functional.cpp meta_functional.cpp adhesion_functional.cpp elasto_plastic_model.cpp volume_potential.cpp kelvin.cpp +mindlin.cpp """.split() model_list = prepend('model', model_list) # Solvers solvers_list = """ contact_solver.cpp polonsky_keer_rey.cpp """.split() solvers_list = prepend('solvers', solvers_list) # GPU API gpu_list = """ fftransform_cufft.cpp """.split() gpu_list = prepend('gpu', gpu_list) # Assembling total list rough_contact_list = \ core_list + generator_list + percolation_list + model_list + solvers_list + bem_list # Adding GPU if needed if env['backend'] == 'cuda': rough_contact_list += gpu_list # Generating dependency files # env.AppendUnique(CXXFLAGS=['-MMD']) # for file_name in rough_contact_list: # obj = file_name.replace('.cpp', '.os') # dep_file_name = file_name.replace('.cpp', '.d') # env.SideEffect(dep_file_name, obj) # env.ParseDepends(dep_file_name) libTamaas = env.SharedLibrary('Tamaas', rough_contact_list) Export('libTamaas') diff --git a/src/model/kelvin.cpp b/src/model/kelvin.cpp index 7b7e1120..5541ccf6 100644 --- a/src/model/kelvin.cpp +++ b/src/model/kelvin.cpp @@ -1,268 +1,268 @@ /** * @file * * @author Lucas Frérot <lucas.frerot@epfl.ch> * * @section LICENSE * * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "kelvin.hh" #include "elasto_plastic_model.hh" #include "influence.hh" /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* Constructors */ /* -------------------------------------------------------------------------- */ template <> Kelvin<model_type::volume_2d, 2>::Kelvin(Model* model) : VolumePotential(model) { initialize(trait::components, trait::components); } template <> Kelvin<model_type::volume_2d, 3>::Kelvin(Model* model) : VolumePotential(model) { initialize(trait::components * trait::components, trait::components); } template <> Kelvin<model_type::volume_2d, 4>::Kelvin(Model* model) : VolumePotential(model) { initialize(trait::components * trait::components, trait::components * trait::components); } /* -------------------------------------------------------------------------- */ /* Operator implementation */ /* -------------------------------------------------------------------------- */ template <> void Kelvin<model_type::volume_2d, 2>::apply(GridBase<Real>& source, GridBase<Real>& out) const { Real nu = model->getPoissonRatio(), mu = model->getShearModulus(); VectorProxy<const Real, trait::dimension> domain(model->getSystemSize()[0]); influence::Kelvin<trait::dimension, 0> kelvin(mu, nu); auto apply = [this, &kelvin](UInt i, decltype(source_buffers)& source_buffers, decltype(disp_buffer)& displacement) { constexpr UInt dim = trait::dimension; const Real L = this->model->getSystemSize().front(); const UInt N = this->model->getDiscretization().front(); const Real dl = L / (N - 1); // Compute displacements u_i displacement = 0; for (UInt j : Loop::range(N)) { const Real dij = j * dl - i * dl; // don't factorize! auto& source = source_buffers[j]; #define POTENTIAL(yj_xi) \ Loop::stridedLoop( \ [&kelvin, dij, dl](VectorProxy<Complex, dim>&& u, \ VectorProxy<Complex, dim>&& f, \ VectorProxy<const Real, dim - 1>&& q) { \ /* Cutoff */ \ if (-q.l2norm() * std::abs(dij) < std::log(1e-2)) \ return; \ influence::KelvinIntegrator<1>::integrate<yj_xi>(u, f, kelvin, q, dij, \ dl); \ }, \ displacement, source, this->wavevectors) if (j > i) { POTENTIAL(1); } else if (j == i) { POTENTIAL(0); } else { POTENTIAL(-1); } #undef POTENTIAL } // Setting fundamental frequency to zero VectorProxy<Complex, dim> u_fundamental(displacement(0)); u_fundamental = 0; }; this->fourierApply(apply, source, out); } /* -------------------------------------------------------------------------- */ template <> void Kelvin<model_type::volume_2d, 3>::apply(GridBase<Real>& source, GridBase<Real>& out) const { Real nu = model->getPoissonRatio(), mu = model->getShearModulus(); VectorProxy<const Real, trait::dimension> domain(model->getSystemSize()[0]); influence::Kelvin<trait::dimension, 1> kelvin(mu, nu); auto apply = [this, &kelvin](UInt i, decltype(source_buffers)& source_buffers, decltype(disp_buffer)& displacement) { constexpr UInt dim = trait::dimension; const Real L = this->model->getSystemSize().front(); const UInt N = this->model->getDiscretization().front(); const Real dl = L / (N - 1); // Compute displacements u_i displacement = 0; for (UInt j : Loop::range(N)) { const Real dij = j * dl - i * dl; // don't factorize! auto& source = source_buffers[j]; #define POTENTIAL(yj_xi) \ Loop::stridedLoop( \ [&kelvin, dij, dl](VectorProxy<Complex, dim>&& u, \ MatrixProxy<Complex, dim, dim>&& f, \ VectorProxy<const Real, dim - 1>&& q) { \ /* Cutoff */ \ if (-q.l2norm() * std::abs(dij) < std::log(1e-2)) \ return; \ influence::KelvinIntegrator<1>::integrate<yj_xi>(u, f, kelvin, q, dij, \ dl); \ }, \ displacement, source, this->wavevectors) if (j > i) { POTENTIAL(1); } else if (j == i) { POTENTIAL(0); } else { POTENTIAL(-1); } #undef POTENTIAL } // Setting fundamental frequency to zero VectorProxy<Complex, dim> u_fundamental(displacement(0)); u_fundamental = 0; }; this->fourierApply(apply, source, out); } /* -------------------------------------------------------------------------- */ template <> void Kelvin<model_type::volume_2d, 4>::apply(GridBase<Real>& source, GridBase<Real>& out) const { Real nu = model->getPoissonRatio(), mu = model->getShearModulus(); VectorProxy<const Real, trait::dimension> domain(model->getSystemSize()[0]); influence::Kelvin<trait::dimension, 2> kelvin(mu, nu); auto apply = [this, &kelvin](UInt i, decltype(source_buffers)& source_buffers, decltype(disp_buffer)& gradu) { constexpr UInt dim = trait::dimension; const Real L = this->model->getSystemSize().front(); const UInt N = this->model->getDiscretization().front(); const Real dl = L / (N - 1); // Compute displacement gradient gradu = 0; for (UInt j : Loop::range(N)) { const Real dij = j * dl - i * dl; // don't factorize! auto& source = source_buffers[j]; #define POTENTIAL(yj_xi) \ Loop::stridedLoop( \ [&kelvin, dij, dl](MatrixProxy<Complex, dim, dim>&& u, \ MatrixProxy<Complex, dim, dim>&& f, \ VectorProxy<const Real, dim - 1>&& q) { \ /* Cutoff */ \ if (-q.l2norm() * std::abs(dij) < std::log(1e-2)) \ return; \ - influence::KelvinIntegrator<0>::integrate<yj_xi>(u, f, kelvin, q, dij, \ + influence::KelvinIntegrator<1>::integrate<yj_xi>(u, f, kelvin, q, dij, \ dl); \ }, \ gradu, source, this->wavevectors) if (j > i) { POTENTIAL(1); } else if (j == i) { POTENTIAL(0); // Additional free term from discontinous Kelvin gradient Loop::stridedLoop( [&kelvin](MatrixProxy<Complex, dim, dim>&& u, MatrixProxy<Complex, dim, dim>&& f, VectorProxy<const Real, dim - 1>&& q) { u += kelvin.applyDiscontinuityTerm(q, f); }, gradu, source, this->wavevectors); } else { POTENTIAL(-1); } #undef POTENTIAL } gradu *= -1; // Setting fundamental frequency to zero MatrixProxy<Complex, dim, dim> u_fundamental(gradu(0)); u_fundamental = 0; }; this->fourierApply(apply, source, out); } /* -------------------------------------------------------------------------- */ template <model_type type, UInt tensor_order> void Kelvin<type, tensor_order>::initialize(UInt source_components, UInt out_components) { // Copy horizontal sizes std::array<UInt, trait::boundary_dimension> sizes; std::copy(this->model->getDiscretization().begin() + 1, this->model->getDiscretization().end(), sizes.begin()); auto hermitian_sizes = GridHermitian<Real, trait::boundary_dimension>::hermitianDimensions( sizes); /// Initializing buffers this->source_buffers.resize(this->model->getDiscretization()[0]); std::for_each(this->source_buffers.begin(), this->source_buffers.end(), [&](typename parent::BufferType& buffer) { buffer.setNbComponents(source_components); buffer.resize(hermitian_sizes); }); this->disp_buffer.setNbComponents(out_components); this->disp_buffer.resize(hermitian_sizes); } /* -------------------------------------------------------------------------- */ template <model_type type, UInt tensor_order> void Kelvin<type, tensor_order>::apply(GridBase<Real>& source, GridBase<Real>& out) const { TAMAAS_EXCEPTION("The requested operator has not been implemented"); } /* -------------------------------------------------------------------------- */ /* Template instanciation */ /* -------------------------------------------------------------------------- */ template class Kelvin<model_type::volume_2d, 2>; template class Kelvin<model_type::volume_2d, 3>; template class Kelvin<model_type::volume_2d, 4>; /* -------------------------------------------------------------------------- */ __END_TAMAAS__ diff --git a/src/model/kelvin.hh b/src/model/kelvin.hh index d58265fa..2b836413 100644 --- a/src/model/kelvin.hh +++ b/src/model/kelvin.hh @@ -1,60 +1,60 @@ /** * @file * * @author Lucas Frérot <lucas.frerot@epfl.ch> * * @section LICENSE * * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#ifndef __KELVIN_HH__ -#define __KELVIN_HH__ +#ifndef KELVIN_HH +#define KELVIN_HH /* -------------------------------------------------------------------------- */ #include "volume_potential.hh" #include "model_type.hh" #include "grid_hermitian.hh" /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ /** * @brief Kelvin tensor */ template <model_type type, UInt tensor_order> class Kelvin : public VolumePotential<type> { static_assert(type == model_type::volume_1d || type == model_type::volume_2d, "Only volume types are supported"); using trait = model_type_traits<type>; using parent = VolumePotential<type>; public: /// Constructor Kelvin(Model * model); private: void initialize(UInt source_components, UInt out_components); public: /// Apply the Kelvin-tensor_order operator void apply(GridBase<Real>& source, GridBase<Real>& out) const override; }; __END_TAMAAS__ -#endif // __KELVIN_HH__ +#endif // KELVIN_HH diff --git a/src/model/kelvin.hh b/src/model/mindlin.cpp similarity index 61% copy from src/model/kelvin.hh copy to src/model/mindlin.cpp index d58265fa..a81b95f4 100644 --- a/src/model/kelvin.hh +++ b/src/model/mindlin.cpp @@ -1,60 +1,48 @@ /** * @file * * @author Lucas Frérot <lucas.frerot@epfl.ch> * * @section LICENSE * * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#ifndef __KELVIN_HH__ -#define __KELVIN_HH__ -/* -------------------------------------------------------------------------- */ -#include "volume_potential.hh" -#include "model_type.hh" -#include "grid_hermitian.hh" +#include "mindlin.hh" +#include "elasto_plastic_model.hh" +#include "influence.hh" /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ +/* -------------------------------------------------------------------------- */ -/** - * @brief Kelvin tensor - */ +/* -------------------------------------------------------------------------- */ template <model_type type, UInt tensor_order> -class Kelvin : public VolumePotential<type> { - static_assert(type == model_type::volume_1d || type == model_type::volume_2d, - "Only volume types are supported"); - using trait = model_type_traits<type>; - using parent = VolumePotential<type>; - -public: - /// Constructor - Kelvin(Model * model); +void Mindlin<type, tensor_order>::apply(GridBase<Real>& source, + GridBase<Real>& out) const { + TAMAAS_EXCEPTION("The requested operator has not been implemented"); +} -private: - void initialize(UInt source_components, UInt out_components); - -public: - /// Apply the Kelvin-tensor_order operator - void apply(GridBase<Real>& source, GridBase<Real>& out) const override; -}; - - __END_TAMAAS__ +/* -------------------------------------------------------------------------- */ +/* Template instanciation */ +/* -------------------------------------------------------------------------- */ +template class Mindlin<model_type::volume_2d, 3>; +template class Mindlin<model_type::volume_2d, 4>; -#endif // __KELVIN_HH__ +/* -------------------------------------------------------------------------- */ +__END_TAMAAS__ diff --git a/src/model/kelvin.hh b/src/model/mindlin.hh similarity index 83% copy from src/model/kelvin.hh copy to src/model/mindlin.hh index d58265fa..cfc88a5f 100644 --- a/src/model/kelvin.hh +++ b/src/model/mindlin.hh @@ -1,60 +1,58 @@ /** * @file * * @author Lucas Frérot <lucas.frerot@epfl.ch> * * @section LICENSE * * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#ifndef __KELVIN_HH__ -#define __KELVIN_HH__ +#ifndef MINDLIN_HH +#define MINDLIN_HH /* -------------------------------------------------------------------------- */ #include "volume_potential.hh" #include "model_type.hh" #include "grid_hermitian.hh" +#include "kelvin.hh" /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ /** - * @brief Kelvin tensor + * @brief Mindlin tensor */ template <model_type type, UInt tensor_order> -class Kelvin : public VolumePotential<type> { +class Mindlin : public Kelvin<type, tensor_order> { static_assert(type == model_type::volume_1d || type == model_type::volume_2d, "Only volume types are supported"); using trait = model_type_traits<type>; - using parent = VolumePotential<type>; + using parent = Kelvin<type, tensor_order>; public: /// Constructor - Kelvin(Model * model); - -private: - void initialize(UInt source_components, UInt out_components); + using parent::parent; public: - /// Apply the Kelvin-tensor_order operator + /// Apply the Mindlin-tensor_order operator void apply(GridBase<Real>& source, GridBase<Real>& out) const override; }; __END_TAMAAS__ -#endif // __KELVIN_HH__ +#endif // MINDLIN_HH