11#include <kernel/assembly/asm_traits.hpp> 
   13#include <kernel/util/math.hpp> 
   14#include <kernel/geometry/intern/coarse_fine_cell_mapping.hpp> 
   15#include <kernel/geometry/mesh_permutation.hpp> 
   16#include <kernel/trafo/inverse_mapping.hpp> 
   48          Exception(
"local mass matrix inversion error")
 
   80        typename CoarseSpace_>
 
   84        const FineSpace_& fine_space,
 
   85        const CoarseSpace_& coarse_space,
 
   86        const String& cubature_name)
 
  119        typename CoarseSpace_>
 
  123        const FineSpace_& fine_space,
 
  124        const CoarseSpace_& coarse_space,
 
  128        XASSERTM(matrix.rows() == fine_space.get_num_dofs(), 
"invalid matrix dimensions");
 
  129        XASSERTM(matrix.columns() == coarse_space.get_num_dofs(), 
"invalid matrix dimensions");
 
  130        XASSERTM(vector.size() == fine_space.get_num_dofs(), 
"invalid vector size");
 
  132        typedef typename Matrix_::DataType DataType;
 
  135        typedef typename FineSpace_::TrafoType FineTrafoType;
 
  136        typedef typename CoarseSpace_::TrafoType CoarseTrafoType;
 
  137        typedef typename CoarseSpace_::ShapeType ShapeType;
 
  140        typedef typename FineSpace_::DofMappingType FineDofMapping;
 
  141        typedef typename CoarseSpace_::DofMappingType CoarseDofMapping;
 
  144        typedef typename FineTrafoType::template Evaluator<ShapeType, DataType>::Type FineTrafoEvaluator;
 
  145        typedef typename CoarseTrafoType::template Evaluator<ShapeType, DataType>::Type CoarseTrafoEvaluator;
 
  148        typedef typename FineSpace_::template Evaluator<FineTrafoEvaluator>::Type FineSpaceEvaluator;
 
  149        typedef typename CoarseSpace_::template Evaluator<CoarseTrafoEvaluator>::Type CoarseSpaceEvaluator;
 
  152        typedef typename FineSpaceEvaluator::template ConfigTraits<SpaceTags::value> FineSpaceConfigTraits;
 
  153        typedef typename CoarseSpaceEvaluator::template ConfigTraits<SpaceTags::value> CoarseSpaceConfigTraits;
 
  158        typedef typename FineTrafoEvaluator::template ConfigTraits<fine_trafo_config>::EvalDataType FineTrafoEvalData;
 
  159        typedef typename CoarseTrafoEvaluator::template ConfigTraits<coarse_trafo_config>::EvalDataType CoarseTrafoEvalData;
 
  162        typedef typename FineSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType FineSpaceEvalData;
 
  163        typedef typename CoarseSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType CoarseSpaceEvalData;
 
  166        typedef typename Intern::CubatureTraits<FineTrafoEvaluator>::RuleType CubatureRuleType;
 
  169        const FineTrafoType& fine_trafo = fine_space.get_trafo();
 
  170        const CoarseTrafoType& coarse_trafo = coarse_space.get_trafo();
 
  174          coarse_trafo.get_mesh().get_mesh_permutation().get_perm();
 
  176          fine_trafo.get_mesh().get_mesh_permutation().get_inv_perm();
 
  179        CubatureRuleType fine_cubature(Cubature::ctor_factory, cubature_factory);
 
  180        CubatureRuleType refine_cubature;
 
  181        Cubature::RefineFactoryCore::create(refine_cubature, fine_cubature);
 
  185          typename FineSpace_::MeshType, 
typename CoarseSpace_::MeshType>
 
  186          cfmapping(fine_trafo.get_mesh(), coarse_trafo.get_mesh());
 
  189        FEAT_PRAGMA_OMP(parallel)
 
  191          FineTrafoEvalData fine_trafo_data;
 
  192          CoarseTrafoEvalData coarse_trafo_data;
 
  194          FineSpaceEvalData fine_space_data;
 
  195          CoarseSpaceEvalData coarse_space_data;
 
  198          typename Matrix_::ScatterAxpy scatter_maxpy(matrix);
 
  199          typename Vector_::ScatterAxpy scatter_vaxpy(vector);
 
  202          FineDofMapping fine_dof_mapping(fine_space);
 
  203          CoarseDofMapping coarse_dof_mapping(coarse_space);
 
  206          FineTrafoEvaluator fine_trafo_eval(fine_trafo);
 
  207          CoarseTrafoEvaluator coarse_trafo_eval(coarse_trafo);
 
  210          FineSpaceEvaluator fine_space_eval(fine_space);
 
  211          CoarseSpaceEvaluator coarse_space_eval(coarse_space);
 
  223          int pivot[FineSpaceEvaluator::max_local_dofs];
 
  227          for(
Index ccell = 0; ccell < coarse_trafo_eval.get_num_cells(); ++ccell)
 
  230            coarse_trafo_eval.prepare(ccell);
 
  233            coarse_space_eval.prepare(coarse_trafo_eval);
 
  236            const int coarse_num_loc_dofs = coarse_space_eval.get_num_local_dofs();
 
  239            coarse_dof_mapping.prepare(ccell);
 
  242            const Index ccell_2lvl = (coarse_perm.
empty() ? ccell : coarse_perm.map(ccell));
 
  245            for(
Index child(0); child < cfmapping.get_num_children(); ++child)
 
  248              const Index fcell_2lvl = cfmapping.calc_fcell(ccell_2lvl, child);
 
  251              const Index fcell = (fine_perm.
empty() ? fcell_2lvl : fine_perm.map(fcell_2lvl));
 
  254              fine_trafo_eval.prepare(fcell);
 
  257              fine_space_eval.prepare(fine_trafo_eval);
 
  260              const int fine_num_loc_dofs = fine_space_eval.get_num_local_dofs();
 
  268              for(
int k(0); k < fine_cubature.get_num_points(); ++k)
 
  271                const int l(
int(child) * fine_cubature.get_num_points() + k);
 
  274                fine_trafo_eval(fine_trafo_data, fine_cubature.get_point(k));
 
  275                coarse_trafo_eval(coarse_trafo_data, refine_cubature.get_point(l));
 
  278                fine_space_eval(fine_space_data, fine_trafo_data);
 
  279                coarse_space_eval(coarse_space_data, coarse_trafo_data);
 
  282                for(
int i(0); i < fine_num_loc_dofs; ++i)
 
  285                  for(
int j(0); j < fine_num_loc_dofs; ++j)
 
  287                    mass(i,j) += fine_trafo_data.jac_det * fine_cubature.get_weight(k) *
 
  288                      fine_space_data.phi[i].value * fine_space_data.phi[j].value;
 
  293                  for(
int j(0); j < coarse_num_loc_dofs; ++j)
 
  296                      fine_trafo_data.jac_det * fine_cubature.get_weight(k) *
 
  297                      fine_space_data.phi[i].value * coarse_space_data.phi[j].value;
 
  306              fine_space_eval.finish();
 
  307              fine_trafo_eval.finish();
 
  331              fine_dof_mapping.prepare(fcell);
 
  334              FEAT_PRAGMA_OMP(critical)
 
  337                scatter_maxpy(lid, fine_dof_mapping, coarse_dof_mapping);
 
  340                scatter_vaxpy(lvd, fine_dof_mapping);
 
  344              fine_dof_mapping.finish();
 
  350            coarse_space_eval.finish();
 
  351            coarse_trafo_eval.finish();
 
  354            coarse_dof_mapping.finish();
 
  385        typename CoarseSpace_>
 
  388          const FineSpace_& fine_space,
 
  389          const CoarseSpace_& coarse_space,
 
  390          const String& cubature_name)
 
  420        typename CoarseSpace_>
 
  423        const FineSpace_& fine_space,
 
  424        const CoarseSpace_& coarse_space,
 
  428        auto weight = matrix.create_vector_l();
 
  436        weight.component_invert(weight);
 
  437        matrix.scale_rows(matrix, weight);
 
  467        typename CoarseSpace_>
 
  471        const FineSpace_& fine_space,
 
  472        const CoarseSpace_& coarse_space,
 
  473        const String& cubature_name)
 
  506        typename CoarseSpace_>
 
  510        const FineSpace_& fine_space,
 
  511        const CoarseSpace_& coarse_space,
 
  515        XASSERTM(matrix.rows() == coarse_space.get_num_dofs(), 
"invalid matrix dimensions");
 
  516        XASSERTM(matrix.columns() == fine_space.get_num_dofs(), 
"invalid matrix dimensions");
 
  517        XASSERTM(vector.size() == coarse_space.get_num_dofs(), 
"invalid vector size");
 
  519        typedef typename Matrix_::DataType DataType;
 
  522        typedef typename FineSpace_::TrafoType FineTrafoType;
 
  523        typedef typename CoarseSpace_::TrafoType CoarseTrafoType;
 
  524        typedef typename CoarseSpace_::ShapeType ShapeType;
 
  527        typedef typename FineSpace_::DofMappingType FineDofMapping;
 
  528        typedef typename CoarseSpace_::DofMappingType CoarseDofMapping;
 
  531        typedef typename FineTrafoType::template Evaluator<ShapeType, DataType>::Type FineTrafoEvaluator;
 
  532        typedef typename CoarseTrafoType::template Evaluator<ShapeType, DataType>::Type CoarseTrafoEvaluator;
 
  535        typedef typename FineSpace_::template Evaluator<FineTrafoEvaluator>::Type FineSpaceEvaluator;
 
  536        typedef typename CoarseSpace_::template Evaluator<CoarseTrafoEvaluator>::Type CoarseSpaceEvaluator;
 
  539        typedef typename FineSpaceEvaluator::template ConfigTraits<SpaceTags::value> FineSpaceConfigTraits;
 
  540        typedef typename CoarseSpaceEvaluator::template ConfigTraits<SpaceTags::value> CoarseSpaceConfigTraits;
 
  545        typedef typename FineTrafoEvaluator::template ConfigTraits<fine_trafo_config>::EvalDataType FineTrafoEvalData;
 
  546        typedef typename CoarseTrafoEvaluator::template ConfigTraits<coarse_trafo_config>::EvalDataType CoarseTrafoEvalData;
 
  549        typedef typename FineSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType FineSpaceEvalData;
 
  550        typedef typename CoarseSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType CoarseSpaceEvalData;
 
  553        typedef typename Intern::CubatureTraits<FineTrafoEvaluator>::RuleType CubatureRuleType;
 
  556        const FineTrafoType& fine_trafo = fine_space.get_trafo();
 
  557        const CoarseTrafoType& coarse_trafo = coarse_space.get_trafo();
 
  561          typename FineSpace_::MeshType, 
typename CoarseSpace_::MeshType>
 
  562          cfmapping(fine_trafo.get_mesh(), coarse_trafo.get_mesh());
 
  566          coarse_trafo.get_mesh().get_mesh_permutation().get_perm();
 
  568          fine_trafo.get_mesh().get_mesh_permutation().get_inv_perm();
 
  571        CubatureRuleType coarse_cubature(Cubature::ctor_factory, cubature_factory);
 
  572        CubatureRuleType fine_cubature(Cubature::ctor_factory, cubature_factory);
 
  573        CubatureRuleType refine_cubature;
 
  574        Cubature::RefineFactoryCore::create(refine_cubature, fine_cubature);
 
  576        FEAT_PRAGMA_OMP(parallel)
 
  578          FineTrafoEvalData fine_trafo_data;
 
  579          CoarseTrafoEvalData coarse_trafo_data;
 
  580          FineSpaceEvalData fine_space_data;
 
  581          CoarseSpaceEvalData coarse_space_data;
 
  584          typename Matrix_::ScatterAxpy scatter_maxpy(matrix);
 
  585          typename Vector_::ScatterAxpy scatter_vaxpy(vector);
 
  588          FineDofMapping fine_dof_mapping(fine_space);
 
  589          CoarseDofMapping coarse_dof_mapping(coarse_space);
 
  592          FineTrafoEvaluator fine_trafo_eval(fine_trafo);
 
  593          CoarseTrafoEvaluator coarse_trafo_eval(coarse_trafo);
 
  596          FineSpaceEvaluator fine_space_eval(fine_space);
 
  597          CoarseSpaceEvaluator coarse_space_eval(coarse_space);
 
  609          int pivot[CoarseSpaceEvaluator::max_local_dofs];
 
  613          for(
Index ccell = 0; ccell < coarse_trafo_eval.get_num_cells(); ++ccell)
 
  616            coarse_trafo_eval.prepare(ccell);
 
  619            coarse_space_eval.prepare(coarse_trafo_eval);
 
  622            const int coarse_num_loc_dofs = coarse_space_eval.get_num_local_dofs();
 
  625            coarse_dof_mapping.prepare(ccell);
 
  629            for(
int k(0); k < coarse_cubature.get_num_points(); ++k)
 
  632              coarse_trafo_eval(coarse_trafo_data, coarse_cubature.get_point(k));
 
  633              coarse_space_eval(coarse_space_data, coarse_trafo_data);
 
  636              for(
int i(0); i < coarse_num_loc_dofs; ++i)
 
  639                for(
int j(0); j < coarse_num_loc_dofs; ++j)
 
  641                  mass(i,j) += coarse_trafo_data.jac_det * coarse_cubature.get_weight(k) *
 
  642                    coarse_space_data.phi[i].value * coarse_space_data.phi[j].value;
 
  651            const Index ccell_2lvl = (coarse_perm.
empty() ? ccell : coarse_perm.map(ccell));
 
  654            for(
Index child(0); child < cfmapping.get_num_children(); ++child)
 
  657              const Index fcell_2lvl = cfmapping.calc_fcell(ccell_2lvl, child);
 
  660              const Index fcell = (fine_perm.
empty() ? fcell_2lvl : fine_perm.map(fcell_2lvl));
 
  663              fine_trafo_eval.prepare(fcell);
 
  666              fine_space_eval.prepare(fine_trafo_eval);
 
  669              const int fine_num_loc_dofs = fine_space_eval.get_num_local_dofs();
 
  675              for(
int k(0); k < fine_cubature.get_num_points(); ++k)
 
  678                const int l(
int(child) * fine_cubature.get_num_points() + k);
 
  681                fine_trafo_eval(fine_trafo_data, fine_cubature.get_point(k));
 
  682                coarse_trafo_eval(coarse_trafo_data, refine_cubature.get_point(l));
 
  685                fine_space_eval(fine_space_data, fine_trafo_data);
 
  686                coarse_space_eval(coarse_space_data, coarse_trafo_data);
 
  689                for(
int i(0); i < coarse_num_loc_dofs; ++i)
 
  692                  for(
int j(0); j < fine_num_loc_dofs; ++j)
 
  695                      fine_trafo_data.jac_det * fine_cubature.get_weight(k) *
 
  696                      coarse_space_data.phi[i].value * fine_space_data.phi[j].value;
 
  705              fine_space_eval.finish();
 
  706              fine_trafo_eval.finish();
 
  716              fine_dof_mapping.prepare(fcell);
 
  719              FEAT_PRAGMA_OMP(critical)
 
  721                scatter_maxpy(lid, coarse_dof_mapping, fine_dof_mapping);
 
  725              fine_dof_mapping.finish();
 
  732            FEAT_PRAGMA_OMP(critical)
 
  734              scatter_vaxpy(lvd, coarse_dof_mapping);
 
  738            coarse_dof_mapping.finish();
 
  741            coarse_space_eval.finish();
 
  742            coarse_trafo_eval.finish();
 
  773        typename CoarseSpace_>
 
  776        const FineSpace_& fine_space,
 
  777        const CoarseSpace_& coarse_space,
 
  778        const String& cubature_name)
 
  808        typename CoarseSpace_>
 
  811        const FineSpace_& fine_space,
 
  812        const CoarseSpace_& coarse_space,
 
  816        auto weight = matrix.create_vector_l();
 
  824        weight.component_invert(weight);
 
  825        matrix.scale_rows(matrix, weight);
 
  872        typename TargetSpace_,
 
  873        typename SourceSpace_,
 
  874        typename Target2SourceAdjactor_>
 
  878        const TargetSpace_& space_target,
 
  879        const SourceSpace_& space_source,
 
  880        const Target2SourceAdjactor_& trg2src,
 
  881        const String& cubature_name)
 
  884        XASSERTM(matrix.rows() == space_target.get_num_dofs(), 
"invalid matrix dimensions");
 
  885        XASSERTM(matrix.columns() == space_source.get_num_dofs(), 
"invalid matrix dimensions");
 
  886        XASSERTM(vector.size() == space_target.get_num_dofs(), 
"invalid vector size");
 
  888        typedef typename Matrix_::DataType DataType;
 
  891        typedef typename TargetSpace_::TrafoType TargetTrafoType;
 
  892        typedef typename SourceSpace_::TrafoType SourceTrafoType;
 
  893        typedef typename SourceSpace_::ShapeType ShapeType;
 
  896        typedef typename TargetSpace_::DofMappingType TargetDofMapping;
 
  897        typedef typename SourceSpace_::DofMappingType SourceDofMapping;
 
  900        typedef typename TargetTrafoType::template Evaluator<ShapeType, DataType>::Type TargetTrafoEvaluator;
 
  901        typedef typename SourceTrafoType::template Evaluator<ShapeType, DataType>::Type SourceTrafoEvaluator;
 
  904        typedef typename TargetSpace_::template Evaluator<TargetTrafoEvaluator>::Type TargetSpaceEvaluator;
 
  905        typedef typename SourceSpace_::template Evaluator<SourceTrafoEvaluator>::Type SourceSpaceEvaluator;
 
  908        typedef typename TargetSpaceEvaluator::template ConfigTraits<SpaceTags::value> TargetSpaceConfigTraits;
 
  909        typedef typename SourceSpaceEvaluator::template ConfigTraits<SpaceTags::value> SourceSpaceConfigTraits;
 
  914        typedef typename TargetTrafoEvaluator::template ConfigTraits<target_trafo_config>::EvalDataType TargetTrafoEvalData;
 
  915        typedef typename SourceTrafoEvaluator::template ConfigTraits<source_trafo_config>::EvalDataType SourceTrafoEvalData;
 
  918        typedef typename TargetSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType TargetSpaceEvalData;
 
  919        typedef typename SourceSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType SourceSpaceEvalData;
 
  923        typedef typename SourceInverseMappingType::InvMapDataType SourceInvMapData;
 
  926        typedef typename Intern::CubatureTraits<TargetTrafoEvaluator>::RuleType CubatureRuleType;
 
  935        const TargetTrafoType& target_trafo = space_target.get_trafo();
 
  936        const SourceTrafoType& source_trafo = space_source.get_trafo();
 
  940        CubatureRuleType target_cubature(Cubature::ctor_factory, cubature_factory);
 
  941        const std::size_t num_cub_pts = std::size_t(target_cubature.get_num_points());
 
  944        int failed_points = 0;
 
  947        FEAT_PRAGMA_OMP(parallel reduction(+:failed_points))
 
  950          typename Matrix_::ScatterAxpy scatter_maxpy(matrix);
 
  951          typename Vector_::ScatterAxpy scatter_vaxpy(vector);
 
  954          TargetDofMapping target_dof_mapping(space_target);
 
  955          SourceDofMapping source_dof_mapping(space_source);
 
  958          TargetTrafoEvaluator target_trafo_eval(target_trafo);
 
  959          SourceTrafoEvaluator source_trafo_eval(source_trafo);
 
  962          TargetSpaceEvaluator space_target_eval(space_target);
 
  963          SourceSpaceEvaluator space_source_eval(space_source);
 
  965          TargetTrafoEvalData target_trafo_data;
 
  966          SourceTrafoEvalData source_trafo_data;
 
  967          TargetSpaceEvalData space_target_data;
 
  968          SourceSpaceEvalData space_source_data;
 
  972          std::vector<TargetBasisValueVector> target_basis_values;
 
  973          target_basis_values.resize(num_cub_pts);
 
  976          SourceInverseMappingType source_inv_map(source_trafo);
 
  979          std::vector<SourceInvMapData> source_inv_map_data;
 
  980          source_inv_map_data.resize(num_cub_pts);
 
  983          std::vector<std::vector<std::pair<std::size_t, std::size_t>>> source_cell_map;
 
  984          source_cell_map.reserve(30);
 
  987          LocTrgMatrixType trg_mass;
 
  990          LocTSIMatrixType tsi_mass;
 
  993          std::vector<LocTSIMatrixType> loc_trans;
 
  994          loc_trans.reserve(30);
 
 1001          int pivot[TargetSpaceEvaluator::max_local_dofs];
 
 1005          FEAT_PRAGMA_OMP(
for schedule(dynamic,16))
 
 1006          for(std::int64_t itrg_cell = 0ull; itrg_cell < std::int64_t(target_trafo_eval.get_num_cells()); ++itrg_cell)
 
 1012            std::vector<Index> source_cells;
 
 1013            for(
auto it = trg2src.image_begin(trg_cell); it != trg2src.image_end(trg_cell); ++it)
 
 1014              source_cells.push_back(*it);
 
 1017            source_cell_map.resize(source_cells.size());
 
 1020            loc_trans.resize(source_cells.size());
 
 1023            target_trafo_eval.prepare(trg_cell);
 
 1026            space_target_eval.prepare(target_trafo_eval);
 
 1029            const int target_num_loc_dofs = space_target_eval.get_num_local_dofs();
 
 1036            for(std::size_t k(0); k < num_cub_pts; ++k)
 
 1039              target_trafo_eval(target_trafo_data, target_cubature.get_point(
int(k)));
 
 1042              space_target_eval(space_target_data, target_trafo_data);
 
 1045              for(
int i(0); i < target_num_loc_dofs; ++i)
 
 1048                target_basis_values.at(k)[i] = target_trafo_data.jac_det * target_cubature.get_weight(
int(k)) * space_target_data.phi[i].value;
 
 1049                for(
int j(0); j < target_num_loc_dofs; ++j)
 
 1051                  trg_mass(i,j) += target_basis_values.at(k)[i] * space_target_data.phi[j].value;
 
 1056              SourceInvMapData& simd = source_inv_map_data.at(k);
 
 1057              simd = source_inv_map.unmap_point(target_trafo_data.img_point, source_cells, 
false);
 
 1068              for(std::size_t i(0); i < simd.size(); ++i)
 
 1071                std::size_t loc_idx = 0u;
 
 1072                for(; loc_idx < source_cells.size(); ++loc_idx)
 
 1073                  if(source_cells.at(loc_idx) == simd.cells.at(i))
 
 1075                XASSERT(loc_idx < source_cells.size());
 
 1078                source_cell_map.at(loc_idx).push_back(std::make_pair(i, k));
 
 1083            space_target_eval.finish();
 
 1084            target_trafo_eval.finish();
 
 1101            for(std::size_t is = 0u; is < source_cell_map.size(); ++is)
 
 1104              const Index src_cell = source_cells.at(is);
 
 1107              std::vector<std::pair<std::size_t, std::size_t>> cub_pts_map = source_cell_map.at(is);
 
 1110              if(cub_pts_map.empty())
 
 1114              source_trafo_eval.prepare(src_cell);
 
 1117              space_source_eval.prepare(source_trafo_eval);
 
 1120              const int source_num_loc_dofs = space_source_eval.get_num_local_dofs();
 
 1126              for(
auto cit = cub_pts_map.begin(); cit != cub_pts_map.end(); ++cit)
 
 1129                const std::size_t src_i = cit->first;
 
 1132                const std::size_t cub_k = cit->second;
 
 1135                SourceInvMapData& simd = source_inv_map_data.at(cub_k);
 
 1138                XASSERT(simd.cells.at(src_i) == src_cell);
 
 1142                DataType weight = DataType(1) / DataType(simd.size());
 
 1145                source_trafo_eval(source_trafo_data, simd.dom_points.at(src_i));
 
 1148                space_source_eval(space_source_data, source_trafo_data);
 
 1151                for(
int i(0); i < target_num_loc_dofs; ++i)
 
 1152                  for(
int j(0); j < source_num_loc_dofs; ++j)
 
 1153                    tsi_mass(i, j) += weight * target_basis_values.at(cub_k)[i] * space_source_data.phi[j].value;
 
 1158              space_source_eval.finish();
 
 1159              source_trafo_eval.finish();
 
 1162              loc_trans.at(is).set_mat_mat_mult(trg_mass, tsi_mass);
 
 1171            target_dof_mapping.prepare(trg_cell);
 
 1174            FEAT_PRAGMA_OMP(critical)
 
 1177              for(std::size_t is = 0u; is < source_cells.size(); ++is)
 
 1180                if(source_cell_map.at(is).empty())
 
 1184                source_dof_mapping.prepare(source_cells.at(is));
 
 1187                scatter_maxpy(loc_trans.at(is), target_dof_mapping, source_dof_mapping);
 
 1190                source_dof_mapping.finish();
 
 1193                source_cell_map.at(is).clear();
 
 1197              scatter_vaxpy(lvd, target_dof_mapping);
 
 1201            target_dof_mapping.finish();
 
 1206        return failed_points;
 
 1242        typename TargetSpace_,
 
 1243        typename SourceSpace_,
 
 1244        typename Target2SourceAdjactor_>
 
 1247        const TargetSpace_& space_target,
 
 1248        const SourceSpace_& space_source,
 
 1249        const Target2SourceAdjactor_& trg2src,
 
 1250        const String& cubature_name)
 
 1253        auto weight = matrix.create_vector_l();
 
 1261        weight.component_invert(weight);
 
 1262        matrix.scale_rows(matrix, weight);
 
 1301        typename FineSpace_,
 
 1302        typename CoarseSpace_>
 
 1306        const Vector_& vector_c,
 
 1307        const FineSpace_& fine_space,
 
 1308        const CoarseSpace_& coarse_space,
 
 1309        const String& cubature_name)
 
 1312        XASSERTM(vector_f.size() == vector_w.size(), 
"invalid vector sizes");
 
 1313        XASSERTM(vector_f.size() == fine_space.get_num_dofs(), 
"invalid matrix dimensions");
 
 1314        XASSERTM(vector_c.size() == coarse_space.get_num_dofs(), 
"invalid matrix dimensions");
 
 1315        XASSERTM(vector_f.size() == fine_space.get_num_dofs(), 
"invalid vector size");
 
 1317        typedef typename Vector_::DataType DataType;
 
 1318        typedef typename Vector_::ValueType ValueType;
 
 1321        typedef typename FineSpace_::TrafoType FineTrafoType;
 
 1322        typedef typename CoarseSpace_::TrafoType CoarseTrafoType;
 
 1323        typedef typename CoarseSpace_::ShapeType ShapeType;
 
 1326        typedef typename FineSpace_::DofMappingType FineDofMapping;
 
 1327        typedef typename CoarseSpace_::DofMappingType CoarseDofMapping;
 
 1330        typedef typename FineTrafoType::template Evaluator<ShapeType, DataType>::Type FineTrafoEvaluator;
 
 1331        typedef typename CoarseTrafoType::template Evaluator<ShapeType, DataType>::Type CoarseTrafoEvaluator;
 
 1334        typedef typename FineSpace_::template Evaluator<FineTrafoEvaluator>::Type FineSpaceEvaluator;
 
 1335        typedef typename CoarseSpace_::template Evaluator<CoarseTrafoEvaluator>::Type CoarseSpaceEvaluator;
 
 1338        typedef typename FineSpaceEvaluator::template ConfigTraits<SpaceTags::value> FineSpaceConfigTraits;
 
 1339        typedef typename CoarseSpaceEvaluator::template ConfigTraits<SpaceTags::value> CoarseSpaceConfigTraits;
 
 1344        typedef typename FineTrafoEvaluator::template ConfigTraits<fine_trafo_config>::EvalDataType FineTrafoEvalData;
 
 1345        typedef typename CoarseTrafoEvaluator::template ConfigTraits<coarse_trafo_config>::EvalDataType CoarseTrafoEvalData;
 
 1346        FineTrafoEvalData fine_trafo_data;
 
 1347        CoarseTrafoEvalData coarse_trafo_data;
 
 1350        typedef typename FineSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType FineSpaceEvalData;
 
 1351        typedef typename CoarseSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType CoarseSpaceEvalData;
 
 1352        FineSpaceEvalData fine_space_data;
 
 1353        CoarseSpaceEvalData coarse_space_data;
 
 1356        typedef typename Assembly::Intern::CubatureTraits<FineTrafoEvaluator>::RuleType CubatureRuleType;
 
 1359        typename Vector_::GatherAxpy gather_c(vector_c);
 
 1360        typename Vector_::ScatterAxpy scatter_f(vector_f);
 
 1361        typename Vector_::ScatterAxpy scatter_w(vector_w);
 
 1364        FineDofMapping fine_dof_mapping(fine_space);
 
 1365        CoarseDofMapping coarse_dof_mapping(coarse_space);
 
 1368        const FineTrafoType& fine_trafo = fine_space.get_trafo();
 
 1369        const CoarseTrafoType& coarse_trafo = coarse_space.get_trafo();
 
 1372        FineTrafoEvaluator fine_trafo_eval(fine_trafo);
 
 1373        CoarseTrafoEvaluator coarse_trafo_eval(coarse_trafo);
 
 1376        FineSpaceEvaluator fine_space_eval(fine_space);
 
 1377        CoarseSpaceEvaluator coarse_space_eval(coarse_space);
 
 1381        CubatureRuleType fine_cubature(Cubature::ctor_factory, cubature_factory);
 
 1382        CubatureRuleType refine_cubature;
 
 1383        Cubature::RefineFactoryCore::create(refine_cubature, fine_cubature);
 
 1395        int pivot[FineSpaceEvaluator::max_local_dofs];
 
 1399          typename FineSpace_::MeshType, 
typename CoarseSpace_::MeshType>
 
 1400          cfmapping(fine_trafo.get_mesh(), coarse_trafo.get_mesh());
 
 1404          coarse_trafo.get_mesh().get_mesh_permutation().get_perm();
 
 1406          fine_trafo.get_mesh().get_mesh_permutation().get_inv_perm();
 
 1409        for(
Index ccell(0); ccell < coarse_trafo_eval.get_num_cells(); ++ccell)
 
 1412          coarse_trafo_eval.prepare(ccell);
 
 1415          coarse_space_eval.prepare(coarse_trafo_eval);
 
 1418          const int coarse_num_loc_dofs = coarse_space_eval.get_num_local_dofs();
 
 1421          coarse_dof_mapping.prepare(ccell);
 
 1425          gather_c(lv_c, coarse_dof_mapping);
 
 1428          const Index ccell_2lvl = (coarse_perm.
empty() ? ccell : coarse_perm.map(ccell));
 
 1431          for(
Index child(0); child < cfmapping.get_num_children(); ++child)
 
 1434            const Index fcell_2lvl = cfmapping.calc_fcell(ccell_2lvl, child);
 
 1437            const Index fcell = (fine_perm.
empty() ? fcell_2lvl : fine_perm.map(fcell_2lvl));
 
 1440            fine_trafo_eval.prepare(fcell);
 
 1443            fine_space_eval.prepare(fine_trafo_eval);
 
 1446            const int fine_num_loc_dofs = fine_space_eval.get_num_local_dofs();
 
 1455            for(
int k(0); k < fine_cubature.get_num_points(); ++k)
 
 1458              const int l(
int(child) * fine_cubature.get_num_points() + k);
 
 1461              fine_trafo_eval(fine_trafo_data, fine_cubature.get_point(k));
 
 1462              coarse_trafo_eval(coarse_trafo_data, refine_cubature.get_point(l));
 
 1465              fine_space_eval(fine_space_data, fine_trafo_data);
 
 1466              coarse_space_eval(coarse_space_data, coarse_trafo_data);
 
 1469              for(
int i(0); i < fine_num_loc_dofs; ++i)
 
 1472                for(
int j(0); j < fine_num_loc_dofs; ++j)
 
 1474                  mass(i,j) += fine_trafo_data.jac_det * fine_cubature.get_weight(k) *
 
 1475                    fine_space_data.phi[i].value * fine_space_data.phi[j].value;
 
 1480                for(
int j(0); j < coarse_num_loc_dofs; ++j)
 
 1483                    fine_trafo_data.jac_det * fine_cubature.get_weight(k) *
 
 1484                    fine_space_data.phi[i].value * coarse_space_data.phi[j].value;
 
 1493            fine_space_eval.finish();
 
 1494            fine_trafo_eval.finish();
 
 1519            for(
int i(0); i < fine_num_loc_dofs; ++i)
 
 1520              for(
int j(0); j < coarse_num_loc_dofs; ++j)
 
 1521                lv_f[i] += lid[i][j] * lv_c[j];
 
 1524            fine_dof_mapping.prepare(fcell);
 
 1527            scatter_f(lv_f, fine_dof_mapping);
 
 1530            lv_w.
format(DataType(1));
 
 1531            scatter_w(lv_w, fine_dof_mapping);
 
 1534            fine_dof_mapping.finish();
 
 1540          coarse_space_eval.finish();
 
 1541          coarse_trafo_eval.finish();
 
 1544          coarse_dof_mapping.finish();
 
 1575        typename FineSpace_,
 
 1576        typename CoarseSpace_>
 
 1579        const Vector_& vector_c,
 
 1580        const FineSpace_& fine_space,
 
 1581        const CoarseSpace_& coarse_space,
 
 1582        const String& cubature_name)
 
 1587        prolongate_vector(vector_f, vector_w, vector_c, fine_space, coarse_space, cubature_name);
 
 1590        vector_w.component_invert(vector_w);
 
 1591        vector_f.component_product(vector_f, vector_w);
 
 1642        typename TargetSpace_,
 
 1643        typename SourceSpace_,
 
 1644        typename Target2SourceAdjactor_>
 
 1646        Vector_& vector_target,
 
 1647        Vector_& vector_weight,
 
 1648        const Vector_& vector_source,
 
 1649        const TargetSpace_& space_target,
 
 1650        const SourceSpace_& space_source,
 
 1651        const Target2SourceAdjactor_& trg2src,
 
 1652        const String& cubature_name)
 
 1655        XASSERTM(vector_target.size() == space_target.get_num_dofs(), 
"invalid vector size");
 
 1656        XASSERTM(vector_weight.size() == space_target.get_num_dofs(), 
"invalid vector size");
 
 1657        XASSERTM(vector_source.size() == space_source.get_num_dofs(), 
"invalid vector size");
 
 1659        typedef typename Vector_::DataType DataType;
 
 1660        typedef typename Vector_::ValueType ValueType;
 
 1663        typedef typename TargetSpace_::TrafoType TargetTrafoType;
 
 1664        typedef typename SourceSpace_::TrafoType SourceTrafoType;
 
 1665        typedef typename SourceSpace_::ShapeType ShapeType;
 
 1668        typedef typename TargetSpace_::DofMappingType TargetDofMapping;
 
 1669        typedef typename SourceSpace_::DofMappingType SourceDofMapping;
 
 1672        typedef typename TargetTrafoType::template Evaluator<ShapeType, DataType>::Type TargetTrafoEvaluator;
 
 1673        typedef typename SourceTrafoType::template Evaluator<ShapeType, DataType>::Type SourceTrafoEvaluator;
 
 1676        typedef typename TargetSpace_::template Evaluator<TargetTrafoEvaluator>::Type TargetSpaceEvaluator;
 
 1677        typedef typename SourceSpace_::template Evaluator<SourceTrafoEvaluator>::Type SourceSpaceEvaluator;
 
 1680        typedef typename TargetSpaceEvaluator::template ConfigTraits<SpaceTags::value> TargetSpaceConfigTraits;
 
 1681        typedef typename SourceSpaceEvaluator::template ConfigTraits<SpaceTags::value> SourceSpaceConfigTraits;
 
 1686        typedef typename TargetTrafoEvaluator::template ConfigTraits<target_trafo_config>::EvalDataType TargetTrafoEvalData;
 
 1687        typedef typename SourceTrafoEvaluator::template ConfigTraits<source_trafo_config>::EvalDataType SourceTrafoEvalData;
 
 1690        typedef typename TargetSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType TargetSpaceEvalData;
 
 1691        typedef typename SourceSpaceEvaluator::template ConfigTraits<SpaceTags::value>::EvalDataType SourceSpaceEvalData;
 
 1695        typedef typename SourceInverseMappingType::InvMapDataType SourceInvMapData;
 
 1698        typedef typename Intern::CubatureTraits<TargetTrafoEvaluator>::RuleType CubatureRuleType;
 
 1711        const TargetTrafoType& target_trafo = space_target.get_trafo();
 
 1712        const SourceTrafoType& source_trafo = space_source.get_trafo();
 
 1716        CubatureRuleType target_cubature(Cubature::ctor_factory, cubature_factory);
 
 1717        const std::size_t num_cub_pts = std::size_t(target_cubature.get_num_points());
 
 1720        int failed_points = 0;
 
 1723        FEAT_PRAGMA_OMP(parallel reduction(+:failed_points))
 
 1726          typename Vector_::GatherAxpy gather_s(vector_source);
 
 1727          typename Vector_::ScatterAxpy scatter_t(vector_target);
 
 1728          typename Vector_::ScatterAxpy scatter_w(vector_weight);
 
 1731          TargetDofMapping target_dof_mapping(space_target);
 
 1732          SourceDofMapping source_dof_mapping(space_source);
 
 1735          TargetTrafoEvaluator target_trafo_eval(target_trafo);
 
 1736          SourceTrafoEvaluator source_trafo_eval(source_trafo);
 
 1739          TargetSpaceEvaluator space_target_eval(space_target);
 
 1740          SourceSpaceEvaluator space_source_eval(space_source);
 
 1742          TargetTrafoEvalData target_trafo_data;
 
 1743          SourceTrafoEvalData source_trafo_data;
 
 1744          TargetSpaceEvalData space_target_data;
 
 1745          SourceSpaceEvalData space_source_data;
 
 1749          std::vector<TargetBasisValueVector> target_basis_values;
 
 1750          target_basis_values.resize(num_cub_pts);
 
 1753          SourceInverseMappingType source_inv_map(source_trafo);
 
 1756          std::vector<SourceInvMapData> source_inv_map_data;
 
 1757          source_inv_map_data.resize(num_cub_pts);
 
 1760          std::vector<std::vector<std::pair<std::size_t, std::size_t>>> source_cell_map;
 
 1761          source_cell_map.reserve(30);
 
 1764          LocTrgMatrixType trg_mass;
 
 1765          LocTSIMatrixType tsi_mass, loc_trans;
 
 1766          LocTrgVectorType loc_trg, loc_weight;
 
 1767          LocSrcVectorType loc_src;
 
 1770          loc_weight.format(DataType(1));
 
 1773          int pivot[TargetSpaceEvaluator::max_local_dofs];
 
 1777          FEAT_PRAGMA_OMP(
for schedule(dynamic,16))
 
 1778          for(std::int64_t itrg_cell = 0ull; itrg_cell < std::int64_t(target_trafo_eval.get_num_cells()); ++itrg_cell)
 
 1784            std::vector<Index> source_cells;
 
 1785            for(
auto it = trg2src.image_begin(trg_cell); it != trg2src.image_end(trg_cell); ++it)
 
 1786              source_cells.push_back(*it);
 
 1789            source_cell_map.resize(source_cells.size());
 
 1796            target_trafo_eval.prepare(trg_cell);
 
 1799            space_target_eval.prepare(target_trafo_eval);
 
 1802            const int target_num_loc_dofs = space_target_eval.get_num_local_dofs();
 
 1809            for(std::size_t k(0); k < num_cub_pts; ++k)
 
 1812              target_trafo_eval(target_trafo_data, target_cubature.get_point(
int(k)));
 
 1815              space_target_eval(space_target_data, target_trafo_data);
 
 1818              for(
int i(0); i < target_num_loc_dofs; ++i)
 
 1821                target_basis_values.at(k)[i] = target_trafo_data.jac_det * target_cubature.get_weight(
int(k)) * space_target_data.phi[i].value;
 
 1822                for(
int j(0); j < target_num_loc_dofs; ++j)
 
 1824                  trg_mass(i,j) += target_basis_values.at(k)[i] * space_target_data.phi[j].value;
 
 1829              SourceInvMapData& simd = source_inv_map_data.at(k);
 
 1830              simd = source_inv_map.unmap_point(target_trafo_data.img_point, source_cells, 
false);
 
 1841              for(std::size_t i(0); i < simd.size(); ++i)
 
 1844                std::size_t loc_idx = 0u;
 
 1845                for(; loc_idx < source_cells.size(); ++loc_idx)
 
 1846                  if(source_cells.at(loc_idx) == simd.cells.at(i))
 
 1848                XASSERT(loc_idx < source_cells.size());
 
 1851                source_cell_map.at(loc_idx).push_back(std::make_pair(i, k));
 
 1856            space_target_eval.finish();
 
 1857            target_trafo_eval.finish();
 
 1874            for(std::size_t is = 0u; is < source_cell_map.size(); ++is)
 
 1877              const Index src_cell = source_cells.at(is);
 
 1880              std::vector<std::pair<std::size_t, std::size_t>> cub_pts_map = source_cell_map.at(is);
 
 1883              if(cub_pts_map.empty())
 
 1887              source_trafo_eval.prepare(src_cell);
 
 1890              space_source_eval.prepare(source_trafo_eval);
 
 1893              const int source_num_loc_dofs = space_source_eval.get_num_local_dofs();
 
 1899              for(
auto cit = cub_pts_map.begin(); cit != cub_pts_map.end(); ++cit)
 
 1902                const std::size_t src_i = cit->first;
 
 1905                const std::size_t cub_k = cit->second;
 
 1908                SourceInvMapData& simd = source_inv_map_data.at(cub_k);
 
 1911                XASSERT(simd.cells.at(src_i) == src_cell);
 
 1915                DataType weight = DataType(1) / DataType(simd.size());
 
 1918                source_trafo_eval(source_trafo_data, simd.dom_points.at(src_i));
 
 1921                space_source_eval(space_source_data, source_trafo_data);
 
 1924                for(
int i(0); i < target_num_loc_dofs; ++i)
 
 1925                  for(
int j(0); j < source_num_loc_dofs; ++j)
 
 1926                    tsi_mass(i, j) += weight * target_basis_values.at(cub_k)[i] * space_source_data.phi[j].value;
 
 1931              space_source_eval.finish();
 
 1932              source_trafo_eval.finish();
 
 1935              loc_trans.set_mat_mat_mult(trg_mass, tsi_mass);
 
 1942              source_dof_mapping.prepare(source_cells.at(is));
 
 1946              gather_s(loc_src, source_dof_mapping);
 
 1949              source_dof_mapping.finish();
 
 1952              for(
int i(0); i < target_num_loc_dofs; ++i)
 
 1953                for(
int j(0); j < source_num_loc_dofs; ++j)
 
 1954                  loc_trg[i] += loc_trans[i][j] * loc_src[j];
 
 1959            target_dof_mapping.prepare(trg_cell);
 
 1962            FEAT_PRAGMA_OMP(critical)
 
 1965              scatter_t(loc_trg, target_dof_mapping);
 
 1966              scatter_w(loc_weight, target_dof_mapping);
 
 1970            target_dof_mapping.finish();
 
 1975        return failed_points;
 
 2015        typename TargetSpace_,
 
 2016        typename SourceSpace_,
 
 2017        typename Target2SourceAdjactor_>
 
 2019        Vector_& vector_target,
 
 2020        const Vector_& vector_source,
 
 2021        const TargetSpace_& space_target,
 
 2022        const SourceSpace_& space_source,
 
 2023        const Target2SourceAdjactor_& trg2src,
 
 2024        const String& cubature_name)
 
 2034        weight.component_invert(weight);
 
 2035        vector_target.component_product(vector_target, weight);
 
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
bool empty() const
Checks whether the permutation is empty.
Exception for singular mass matrix errors.
Grid-Transfer assembly class template.
static int assemble_intermesh_transfer(Matrix_ &matrix, Vector_ &vector, const TargetSpace_ &space_target, const SourceSpace_ &space_source, const Target2SourceAdjactor_ &trg2src, const String &cubature_name)
Assembles a generic inter-mesh transfer matrix and its corresponding weight vector.
static void assemble_truncation(Matrix_ &matrix, Vector_ &vector, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Assembles a truncation matrix and its corresponding weight vector.
static void assemble_prolongation_direct(Matrix_ &matrix, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const Cubature::DynamicFactory &cubature_factory)
Assembles a prolongation matrix.
static void assemble_truncation_direct(Matrix_ &matrix, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Assembles a truncation matrix.
static void assemble_truncation(Matrix_ &matrix, Vector_ &vector, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const Cubature::DynamicFactory &cubature_factory)
Assembles a truncation matrix and its corresponding weight vector.
static int transfer_intermesh_vector_direct(Vector_ &vector_target, const Vector_ &vector_source, const TargetSpace_ &space_target, const SourceSpace_ &space_source, const Target2SourceAdjactor_ &trg2src, const String &cubature_name)
Performs a generic inter-mesh transfer of a primal vector directly.
static void assemble_prolongation(Matrix_ &matrix, Vector_ &vector, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const Cubature::DynamicFactory &cubature_factory)
Assembles a prolongation matrix and its corresponding weight vector.
static void assemble_truncation_direct(Matrix_ &matrix, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const Cubature::DynamicFactory &cubature_factory)
Assembles a truncation matrix.
static int transfer_intermesh_vector(Vector_ &vector_target, Vector_ &vector_weight, const Vector_ &vector_source, const TargetSpace_ &space_target, const SourceSpace_ &space_source, const Target2SourceAdjactor_ &trg2src, const String &cubature_name)
Performs a generic inter-mesh transfer of a primal vector and assembles a compatible weight vector.
static int assemble_intermesh_transfer_direct(Matrix_ &matrix, const TargetSpace_ &space_target, const SourceSpace_ &space_source, const Target2SourceAdjactor_ &trg2src, const String &cubature_name)
Assembles a generic inter-mesh transfer matrix and its corresponding weight vector.
static void prolongate_vector(Vector_ &vector_f, Vector_ &vector_w, const Vector_ &vector_c, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Prolongates a primal vector and assembles a compatible weight vector.
static void assemble_prolongation(Matrix_ &matrix, Vector_ &vector, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Assembles a prolongation matrix and its corresponding weight vector.
static void assemble_prolongation_direct(Matrix_ &matrix, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Assembles a prolongation matrix.
static void prolongate_vector_direct(Vector_ &vector_f, const Vector_ &vector_c, const FineSpace_ &fine_space, const CoarseSpace_ &coarse_space, const String &cubature_name)
Prolongates a primal vector directly.
A coarse cell to fine cell mapping class.
String class implementation.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_mat_mat_mult(const Matrix< T_, m_, la_, sma_, sna_ > &a, const Matrix< T_, lb_, n_, smb_, snb_ > &b)
Sets this matrix to the algebraic matrix-product of two other matrices.
static constexpr int sn
the column stride of the matrix
RowType v[sm_]
actual matrix data; that's an array of vectors
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the matrix.
CUDA_HOST_DEVICE DataType norm_frobenius() const
Returns the Frobenius norm of the matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the vector.
Inverse Trafo mapping class template.
LAFEM common type definitions.
bool isnormal(T_ x)
Checks whether a value is normal.
DT_ invert_matrix(const IT_ n, const IT_ stride, DT_ a[], IT_ p[])
Inverts a matrix and returns its determinant.
std::uint64_t Index
Index data type.
TrafoTags
Trafo configuration tags enum.
@ img_point
specifies whether the trafo should supply image point coordinates
@ jac_det
specifies whether the trafo should supply jacobian determinants