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