1
1
//---------------------------------------------------------------------------
2
// $Id: fe_tools.cc 18724 2009-04-23 23:06:37Z bangerth $
2
// $Id: fe_tools.cc 20944 2010-04-06 04:13:47Z bangerth $
5
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
5
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
7
7
// This file is subject to QPL and may not be distributed
8
8
// without copyright and license information. Please refer
252
252
Assert(renumbering.size() == element.dofs_per_cell,
253
253
ExcDimensionMismatch(renumbering.size(),
254
254
element.dofs_per_cell));
256
256
comp_start.resize(element.n_base_elements());
258
258
unsigned int k=0;
259
259
for (unsigned int i=0;i<comp_start.size();++i)
261
261
comp_start[i].resize(element.element_multiplicity(i));
262
262
const unsigned int increment
263
263
= element.base_element(i).dofs_per_cell;
265
265
for (unsigned int j=0;j<comp_start[i].size();++j)
267
267
comp_start[i][j] = k;
272
272
// For each index i of the
273
273
// unstructured cellwise
274
274
// numbering, renumbering
289
289
void FETools::compute_block_renumbering (
290
290
const FiniteElement<dim,spacedim>& element,
291
291
std::vector<unsigned int>& renumbering,
292
std::vector<unsigned int>& start_indices)
292
std::vector<unsigned int>& block_data,
293
bool return_start_indices)
294
295
Assert(renumbering.size() == element.dofs_per_cell,
295
296
ExcDimensionMismatch(renumbering.size(),
296
297
element.dofs_per_cell));
297
Assert(start_indices.size() == element.n_blocks(),
298
ExcDimensionMismatch(start_indices.size(),
298
Assert(block_data.size() == element.n_blocks(),
299
ExcDimensionMismatch(block_data.size(),
299
300
element.n_blocks()));
301
302
unsigned int k=0;
302
303
unsigned int i=0;
303
304
for (unsigned int b=0;b<element.n_base_elements();++b)
304
305
for (unsigned int m=0;m<element.element_multiplicity(b);++m)
306
start_indices[i++] = k;
307
block_data[i++] = (return_start_indices)
309
: (element.base_element(b).n_dofs_per_cell());
307
310
k += element.base_element(b).n_dofs_per_cell();
309
312
Assert (i == element.n_blocks(), ExcInternalError());
310
//TODO:[GK] This does not work for a single RT
314
std::vector<unsigned int> start_indices(block_data.size());
316
for (unsigned int i=0;i<block_data.size();++i)
317
if (return_start_indices)
318
start_indices[i] = block_data[i];
321
start_indices[i] = k;
325
//TODO:[GK] This does not work for a single RT
311
326
for (unsigned int i=0;i<element.dofs_per_cell;++i)
313
328
std::pair<unsigned int, unsigned int>
367
382
Assert(fe2_support_points.size()==fe2.dofs_per_cell,
368
383
typename FEL::ExcFEHasNoSupportPoints());
370
for (unsigned int i=0; i<fe2.dofs_per_cell; ++i)
385
for (unsigned int i=0; i<fe2.dofs_per_cell; ++i)
372
387
const unsigned int i1 = fe2.system_to_component_index(i).first;
373
388
for (unsigned int j=0; j<fe1.dofs_per_cell; ++j)
391
406
Assert (fe1.n_components() == fe2.n_components(),
392
407
ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
393
408
Assert(interpolation_matrix.m()==fe1.dofs_per_cell &&
394
interpolation_matrix.n()==fe1.dofs_per_cell,
409
interpolation_matrix.n()==fe1.dofs_per_cell,
395
410
ExcMatrixDimensionMismatch(interpolation_matrix.m(),
396
411
interpolation_matrix.n(),
397
412
fe1.dofs_per_cell,
398
413
fe1.dofs_per_cell));
400
415
FullMatrix<number> first_matrix (fe2.dofs_per_cell, fe1.dofs_per_cell);
401
416
FullMatrix<number> second_matrix(fe1.dofs_per_cell, fe2.dofs_per_cell);
403
418
get_interpolation_matrix(fe1, fe2, first_matrix);
404
419
get_interpolation_matrix(fe2, fe1, second_matrix);
417
432
Assert (fe1.n_components() == fe2.n_components(),
418
433
ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
419
434
Assert(difference_matrix.m()==fe1.dofs_per_cell &&
420
difference_matrix.n()==fe1.dofs_per_cell,
435
difference_matrix.n()==fe1.dofs_per_cell,
421
436
ExcMatrixDimensionMismatch(difference_matrix.m(),
422
437
difference_matrix.n(),
423
438
fe1.dofs_per_cell,
424
439
fe1.dofs_per_cell));
426
441
FullMatrix<number> interpolation_matrix(fe1.dofs_per_cell);
427
442
get_back_interpolation_matrix(fe1, fe2, interpolation_matrix);
429
444
for (unsigned int i=0; i<fe1.dofs_per_cell; ++i)
430
445
difference_matrix(i,i) = 1.;
432
447
// compute difference
433
448
difference_matrix.add (-1, interpolation_matrix);
457
472
Triangulation<dim,spacedim> tr;
458
473
GridGenerator::hyper_cube(tr);
460
475
// Choose a quadrature rule
461
476
// Gauss is exact up to degree 2n-1
462
477
const unsigned int degree = std::max(fe1.tensor_degree(), fe2.tensor_degree());
463
478
Assert (degree != numbers::invalid_unsigned_int,
464
479
ExcNotImplemented());
466
481
QGauss<dim> quadrature(degree+1);
467
482
// Set up FEValues.
468
483
const UpdateFlags flags = update_values | update_quadrature_points | update_JxW_values;
530
545
Assert (N.m()==n_dofs, ExcDimensionMismatch(N.m(), n_dofs));
532
547
const std::vector<Point<dim> >& points = fe.get_generalized_support_points();
534
549
// We need the values of the
535
550
// polynomials in all generalized
536
551
// support points.
537
552
std::vector<std::vector<double> >
538
553
values (dim, std::vector<double>(points.size()));
540
555
// In this vector, we store the
541
556
// result of the interpolation
542
557
std::vector<double> local_dofs(n_dofs);
544
559
// One row per shape
545
560
// function. Remember that these
546
561
// are the 'raw' shape functions
607
622
Assert(matrices[ref_case-1][i].n() == n, ExcDimensionMismatch(matrices[ref_case-1][i].n(),n));
608
623
Assert(matrices[ref_case-1][i].m() == n, ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
611
626
// Set up meshes, one with a single
612
627
// reference cell and refine it once
613
628
Triangulation<dim,spacedim> tria;
618
633
MappingCartesian<dim> mapping;
619
634
QGauss<dim> q_fine(degree+1);
620
635
const unsigned int nq = q_fine.size();
622
637
FEValues<dim> fine (mapping, fe, q_fine,
623
638
update_quadrature_points | update_JxW_values | update_values);
625
640
// We search for the polynomial on
626
641
// the small cell, being equal to
627
642
// the coarse polynomial in all
628
643
// quadrature points.
630
645
// First build the matrix for this
631
646
// least squares problem. This
632
647
// contains the values of the fine
633
648
// cell polynomials in the fine
634
649
// cell grid points.
636
651
// This matrix is the same for all
638
653
fine.reinit(tria.begin_active());
639
654
FullMatrix<number> A(nq*nd, n);
640
for (unsigned int d=0;d<nd;++d)
641
for (unsigned int k=0;k<nq;++k)
642
for (unsigned int j=0;j<n;++j)
655
for (unsigned int j=0;j<n;++j)
656
for (unsigned int d=0;d<nd;++d)
657
for (unsigned int k=0;k<nq;++k)
643
658
A(k*nd+d,j) = fine.shape_value_component(j,k,d);
645
660
Householder<double> H(A);
647
662
Vector<number> v_coarse(nq*nd);
648
663
Vector<number> v_fine(n);
650
665
unsigned int cell_number = 0;
651
666
for (typename Triangulation<dim>::active_cell_iterator fine_cell
652
667
= tria.begin_active();
675
691
// function values of the
676
692
// coarse grid function in
677
693
// each quadrature point.
678
for (unsigned int d=0;d<nd;++d)
679
for (unsigned int k=0;k<nq;++k)
680
v_coarse(k*nd+d) = coarse.shape_value_component(i,k,d);
694
if (fe.is_primitive())
696
const unsigned int d = fe.system_to_component_index(i).first;
697
const double * phi_i = &coarse.shape_value (i,0);
698
for (unsigned int k=0;k<nq;++k)
699
v_coarse(k*nd+d) = phi_i[k];
702
for (unsigned int d=0;d<nd;++d)
703
for (unsigned int k=0;k<nq;++k)
704
v_coarse(k*nd+d) = coarse.shape_value_component(i,k,d);
682
706
// solve the least squares
684
708
const double result = H.least_squares(v_fine, v_coarse);
685
709
Assert (result < 1.e-12, ExcLeastSquaresError(result));
687
711
// Copy into the result
688
712
// matrix. Since the matrix
689
713
// maps a coarse grid
720
744
const unsigned int n = fe.dofs_per_face;
721
745
const unsigned int nd = fe.n_components();
722
746
const unsigned int degree = fe.degree;
724
748
for (unsigned int i=0;i<nc;++i)
726
750
Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n(),n));
727
751
Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m(),n));
730
754
// Set up meshes, one with a single
731
755
// reference cell and refine it once
732
756
Triangulation<dim,spacedim> tria;
793
817
Assert (k == fe.dofs_per_face, ExcInternalError());
795
819
FEValues<dim> fine (mapping, fe, q_fine,
796
820
update_quadrature_points | update_JxW_values | update_values);
798
822
// We search for the polynomial on
799
823
// the small cell, being equal to
800
824
// the coarse polynomial in all
801
825
// quadrature points.
803
827
// First build the matrix for this
804
828
// least squares problem. This
805
829
// contains the values of the fine
806
830
// cell polynomials in the fine
807
831
// cell grid points.
809
833
// This matrix is the same for all
811
835
fine.reinit(tria.begin_active());
812
836
FullMatrix<number> A(nq*nd, n);
813
for (unsigned int d=0;d<nd;++d)
814
for (unsigned int k=0;k<nq;++k)
815
for (unsigned int j=0;j<n;++j)
837
for (unsigned int j=0;j<n;++j)
838
for (unsigned int d=0;d<nd;++d)
839
for (unsigned int k=0;k<nq;++k)
816
840
A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
818
842
Householder<double> H(A);
820
844
Vector<number> v_coarse(nq*nd);
821
845
Vector<number> v_fine(n);
825
849
for (unsigned int cell_number = 0; cell_number < GeometryInfo<dim>::max_children_per_face;
828
852
const Quadrature<dim> q_coarse
829
853
= QProjector<dim>::project_to_subface(q_gauss, face_coarse, cell_number);
830
854
FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
832
856
typename Triangulation<dim,spacedim>::active_cell_iterator fine_cell
833
857
= tria.begin(0)->child(GeometryInfo<dim>::child_cell_on_face(
834
858
tria.begin(0)->refinement_case(), face_coarse, cell_number));
835
859
fine.reinit(fine_cell);
836
860
coarse.reinit(tria.begin(0));
838
862
FullMatrix<double> &this_matrix = matrices[cell_number];
840
864
// Compute this once for each
841
865
// coarse grid basis function
842
866
for (unsigned int i=0;i<n;++i)
849
873
// each quadrature point.
850
874
for (unsigned int d=0;d<nd;++d)
851
875
for (unsigned int k=0;k<nq;++k)
852
v_coarse(k*nd+d) = coarse.shape_value_component(face_c_dofs[i],k,d);
876
v_coarse(k*nd+d) = coarse.shape_value_component (face_c_dofs[i],k,d);
854
878
// solve the least squares
856
880
const double result = H.least_squares(v_fine, v_coarse);
857
881
Assert (result < 1.e-12, ExcLeastSquaresError(result));
859
883
// Copy into the result
860
884
// matrix. Since the matrix
861
885
// maps a coarse grid
904
928
const unsigned int nd = fe.n_components();
905
929
const unsigned int degree = fe.degree;
931
// prepare FEValues, quadrature etc on
933
MappingCartesian<dim> mapping;
934
QGauss<dim> q_fine(degree+1);
935
const unsigned int nq = q_fine.size();
937
// create mass matrix on coarse cell.
938
FullMatrix<number> mass(n, n);
940
// set up a triangulation for coarse cell
941
Triangulation<dim,spacedim> tr;
942
GridGenerator::hyper_cube (tr, 0, 1);
944
FEValues<dim> coarse (mapping, fe, q_fine,
945
update_JxW_values | update_values);
947
typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
949
coarse.reinit (coarse_cell);
951
const std::vector<double> & JxW = coarse.get_JxW_values();
952
for (unsigned int i=0;i<n;++i)
953
for (unsigned int j=0;j<n;++j)
954
if (fe.is_primitive())
956
const double * coarse_i = &coarse.shape_value(i,0);
957
const double * coarse_j = &coarse.shape_value(j,0);
959
for (unsigned int k=0;k<nq;++k)
960
mass_ij += JxW[k] * coarse_i[k] * coarse_j[k];
966
for (unsigned int d=0;d<nd;++d)
967
for (unsigned int k=0;k<nq;++k)
968
mass_ij += JxW[k] * coarse.shape_value_component(i,k,d)
969
* coarse.shape_value_component(j,k,d);
973
// invert mass matrix
907
977
// loop over all possible refinement cases
908
978
for (unsigned int ref_case = RefinementCase<dim>::cut_x;
909
ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
979
ref_case < RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
911
981
const unsigned int
912
982
nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
918
988
Assert(matrices[ref_case-1][i].m() == n,
919
989
ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
992
// create a respective refinement on the
922
994
Triangulation<dim,spacedim> tr;
923
995
GridGenerator::hyper_cube (tr, 0, 1);
924
996
tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
925
997
tr.execute_coarsening_and_refinement();
927
MappingCartesian<dim> mapping;
928
QGauss<dim> q_fine(degree+1);
929
const unsigned int nq = q_fine.size();
931
FEValues<dim> coarse (mapping, fe, q_fine,
932
update_quadrature_points |
935
999
FEValues<dim> fine (mapping, fe, q_fine,
936
update_quadrature_points |
1000
update_quadrature_points | update_JxW_values |
940
1003
typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
942
// Compute the coarse level mass
944
coarse.reinit(coarse_cell);
945
FullMatrix<number> A(n, n);
946
for (unsigned int k=0;k<nq;++k)
947
for (unsigned int i=0;i<n;++i)
948
for (unsigned int j=0;j<n;++j)
949
if (fe.is_primitive())
950
A(i,j) += coarse.JxW(k)
951
* coarse.shape_value(i,k)
952
* coarse.shape_value(j,k);
954
for (unsigned int d=0;d<nd;++d)
955
A(i,j) = coarse.JxW(k)
956
* coarse.shape_value_component(i,k,d)
957
* coarse.shape_value_component(j,k,d);
959
Householder<double> H(A);
961
1006
Vector<number> v_coarse(n);
962
1007
Vector<number> v_fine(n);
964
1009
for (unsigned int cell_number=0;cell_number<nc;++cell_number)
966
1011
FullMatrix<double> &this_matrix = matrices[ref_case-1][cell_number];
968
1013
// Compute right hand side,
969
1014
// which is a fine level basis
970
1015
// function tested with the
974
1019
fine.get_JxW_values());
975
1020
FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
976
1021
coarse.reinit(coarse_cell);
1025
const std::vector<double> & JxW = fine.get_JxW_values();
980
1027
// Outer loop over all fine
981
1028
// grid shape functions phi_j
982
1029
for (unsigned int j=0;j<fe.dofs_per_cell;++j)
985
// Loop over all quadrature points
986
for (unsigned int k=0;k<fine.n_quadrature_points;++k)
1031
for (unsigned int i=0; i<fe.dofs_per_cell;++i)
988
// integrate the scalar
992
// functions to get the
994
for (unsigned int i=0;i<fe.dofs_per_cell;++i)
996
if (fe.is_primitive())
997
v_fine(i) += fine.JxW(k)
998
* coarse.shape_value(i,k)
999
* fine.shape_value(j,k);
1001
for (unsigned int d=0;d<nd;++d)
1002
v_fine(i) += fine.JxW(k)
1003
* coarse.shape_value_component(i,k,d)
1004
* fine.shape_value_component(j,k,d);
1033
if (fe.is_primitive())
1035
const double * coarse_i = &coarse.shape_value(i,0);
1036
const double * fine_j = &fine.shape_value(j,0);
1039
for (unsigned int k=0; k<nq; ++k)
1040
update += JxW[k] * coarse_i[k] * fine_j[k];
1046
for (unsigned int d=0; d<nd; ++d)
1047
for (unsigned int k=0; k<nq; ++k)
1048
update += JxW[k] * coarse.shape_value_component(i,k,d)
1049
* fine.shape_value_component(j,k,d);
1007
1054
// RHS ready. Solve system
1008
1055
// and enter row into
1010
H.least_squares(v_coarse, v_fine);
1057
mass.vmult (v_coarse, v_fine);
1011
1058
for (unsigned int i=0;i<fe.dofs_per_cell;++i)
1012
1059
this_matrix(i,j) = v_coarse(i);
1015
1062
// Remove small entries from
1017
1064
for (unsigned int i=0; i<this_matrix.m(); ++i)
1036
1083
ConstraintMatrix dummy;
1038
1085
interpolate(dof1, u1, dof2, dummy, u2);
1043
1090
template <int dim, int spacedim,
1044
1091
template <int, int> class DH1,
1045
template <int, int> class DH2,
1092
template <int, int> class DH2,
1046
1093
class InVector, class OutVector>
1048
1095
FETools::interpolate (const DH1<dim, spacedim> &dof1,
1054
1101
Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
1056
1103
Assert(u1.size()==dof1.n_dofs(),
1057
ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1104
ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1058
1105
Assert(u2.size()==dof2.n_dofs(),
1059
1106
ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
1073
1120
std::map<const FiniteElement<dim,spacedim> *,
1074
1121
std_cxx1x::shared_ptr<FullMatrix<double> > > >
1075
1122
interpolation_matrices;
1077
1124
typename DH1<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active(),
1078
1125
endc1 = dof1.end();
1079
1126
typename DH2<dim,spacedim>::active_cell_iterator cell2 = dof2.begin_active(),
1084
1131
dofs.reserve (DoFTools::max_dofs_per_cell (dof2));
1087
for (; cell1!=endc1; ++cell1, ++cell2)
1134
for (; cell1!=endc1; ++cell1, ++cell2)
1089
1136
Assert(cell1->get_fe().n_components() == cell2->get_fe().n_components(),
1090
1137
ExcDimensionMismatch (cell1->get_fe().n_components(),
1100
1147
const bool hanging_nodes_not_allowed
1101
1148
= ((cell2->get_fe().dofs_per_vertex != 0) &&
1102
1149
(constraints.n_constraints() == 0));
1104
1151
if (hanging_nodes_not_allowed)
1105
1152
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
1106
1153
Assert (cell1->at_boundary(face) ||
1107
1154
cell1->neighbor(face)->level() == cell1->level(),
1108
1155
ExcHangingNodesNotAllowed(0));
1111
1158
const unsigned int dofs_per_cell1 = cell1->get_fe().dofs_per_cell;
1112
1159
const unsigned int dofs_per_cell2 = cell2->get_fe().dofs_per_cell;
1113
1160
u1_local.reinit (dofs_per_cell1);
1117
1164
// matrix for this particular
1118
1165
// pair of elements is already
1120
if (interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()] == 0)
1167
if (interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()].get() ==
1122
1170
std_cxx1x::shared_ptr<FullMatrix<double> >
1123
1171
interpolation_matrix (new FullMatrix<double> (dofs_per_cell2,
1124
1172
dofs_per_cell1));
1125
1173
interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()]
1126
1174
= interpolation_matrix;
1128
1176
FETools::get_interpolation_matrix(cell1->get_fe(),
1129
1177
cell2->get_fe(),
1130
1178
*interpolation_matrix);
1133
1181
cell1->get_dof_values(u1, u1_local);
1134
1182
interpolation_matrices[&cell1->get_fe()][&cell2->get_fe()]
1135
1183
->vmult(u2_local, u1_local);
1172
1220
Assert(dof1.get_fe().n_components() == fe2.n_components(),
1173
1221
ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
1174
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1222
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1175
1223
Assert(u1_interpolated.size()==dof1.n_dofs(),
1176
1224
ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
1178
1226
// For continuous elements on grids
1179
1227
// with hanging nodes we need
1180
1228
// hanging node
1190
1238
Vector<typename OutVector::value_type> u1_local(dofs_per_cell1);
1191
1239
Vector<typename OutVector::value_type> u1_int_local(dofs_per_cell1);
1193
1241
typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
1194
1242
endc = dof1.end();
1196
1244
FullMatrix<double> interpolation_matrix(dofs_per_cell1, dofs_per_cell1);
1197
1245
FETools::get_back_interpolation_matrix(dof1.get_fe(), fe2,
1198
1246
interpolation_matrix);
1199
for (; cell!=endc; ++cell)
1247
for (; cell!=endc; ++cell)
1201
1249
if (hanging_nodes_not_allowed)
1202
1250
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
1222
1270
OutVector &u1_interpolated)
1224
1272
Assert(u1.size() == dof1.n_dofs(),
1225
ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1273
ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1226
1274
Assert(u1_interpolated.size() == dof1.n_dofs(),
1227
1275
ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
1229
1277
Vector<typename OutVector::value_type> u1_local(DoFTools::max_dofs_per_cell(dof1));
1230
1278
Vector<typename OutVector::value_type> u1_int_local(DoFTools::max_dofs_per_cell(dof1));
1232
1280
typename DH<dim>::active_cell_iterator cell = dof1.begin_active(),
1233
1281
endc = dof1.end();
1238
1286
std::map<const FiniteElement<dim> *,
1239
1287
std_cxx1x::shared_ptr<FullMatrix<double> > > interpolation_matrices;
1241
for (; cell!=endc; ++cell)
1289
for (; cell!=endc; ++cell)
1243
1291
Assert(cell->get_fe().n_components() == fe2.n_components(),
1244
1292
ExcDimensionMismatch(cell->get_fe().n_components(),
1245
1293
fe2.n_components()));
1247
1295
// For continuous elements on
1248
1296
// grids with hanging nodes we
1249
1297
// need hanging node
1271
1319
(new FullMatrix<double>(dofs_per_cell1, dofs_per_cell1));
1272
1320
get_back_interpolation_matrix(dof1.get_fe(), fe2,
1273
1321
*interpolation_matrices[&cell->get_fe()]);
1276
1324
u1_local.reinit (dofs_per_cell1);
1277
1325
u1_int_local.reinit (dofs_per_cell1);
1279
1327
cell->get_dof_values(u1, u1_local);
1280
1328
interpolation_matrices[&cell->get_fe()]->vmult(u1_int_local, u1_local);
1281
1329
cell->set_dof_values(u1_int_local, u1_interpolated);
1304
1352
Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
1305
1353
ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
1306
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1354
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1307
1355
Assert(u1_interpolated.size()==dof1.n_dofs(),
1308
1356
ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
1310
1358
// For continuous elements
1311
1359
// first interpolate to dof2,
1312
1360
// taking into account
1331
1379
Assert(dof1.get_fe().n_components() == fe2.n_components(),
1332
1380
ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
1333
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1381
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1334
1382
Assert(u1_difference.size()==dof1.n_dofs(),
1335
1383
ExcDimensionMismatch(u1_difference.size(), dof1.n_dofs()));
1337
1385
// For continuous elements on grids
1338
1386
// with hanging nodes we need
1339
1387
// hnaging node
1349
1397
Vector<typename OutVector::value_type> u1_local(dofs_per_cell);
1350
1398
Vector<typename OutVector::value_type> u1_diff_local(dofs_per_cell);
1352
1400
FullMatrix<double> difference_matrix(dofs_per_cell, dofs_per_cell);
1353
1401
FETools::get_interpolation_difference_matrix(dof1.get_fe(), fe2,
1354
1402
difference_matrix);
1356
1404
typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
1357
1405
endc = dof1.end();
1359
1407
for (; cell!=endc; ++cell)
1361
1409
if (hanging_nodes_not_allowed)
1404
1452
Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
1405
1453
Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
1406
1454
ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
1407
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1455
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
1408
1456
Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
1410
1458
typename DoFHandler<dim,spacedim>::active_cell_iterator cell1 = dof1.begin_active();
1414
1462
const unsigned int n1 = dof1.get_fe().dofs_per_cell;
1415
1463
const unsigned int n2 = dof2.get_fe().dofs_per_cell;
1417
1465
Vector<double> u1_local(n1);
1418
1466
Vector<double> u2_local(n2);
1419
1467
std::vector<unsigned int> dofs(n2);
1421
1469
FullMatrix<double> matrix(n2,n1);
1422
1470
get_projection_matrix(dof1.get_fe(), dof2.get_fe(), matrix);
1424
1472
while (cell2 != end)
1426
1474
cell1->get_dof_values(u1, u1_local);
1540
1588
// for this, acquire the lock
1541
1589
// until we quit this function
1542
1590
Threads::ThreadMutex::ScopedLock lock(fe_name_map_lock);
1544
1592
Assert(fe_name_map.find(name) == fe_name_map.end(),
1545
1593
ExcMessage("Cannot change existing element in finite element name list"));
1547
1595
// Insert the normalized name into
1549
1597
fe_name_map[name] = FEFactoryPointer(factory);
1566
1614
name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
1567
1615
const std::string name_part(name, 0, name_end);
1568
1616
name.erase(0, name_part.size());
1570
1618
// now things get a little more
1571
1619
// complicated: FESystem. it's
1572
1620
// more complicated, since we
1730
1778
// Make sure no other thread
1731
1779
// is just adding an element
1732
1780
Threads::ThreadMutex::ScopedLock lock (fe_name_map_lock);
1734
1782
AssertThrow (fe_name_map.find(name_part) != fe_name_map.end(),
1735
1783
FETools::ExcInvalidFEName(name));
1736
1784
// Now, just the (degree)
1751
1799
unsigned int position = name.find('(');
1752
1800
const std::string quadrature_name(name, 0, position-1);
1753
1801
name.erase(0,position);
1754
if (quadrature_name.compare("QGaussLobatto") == 0)
1802
if (quadrature_name.compare("QGaussLobatto") == 0)
1756
1804
const std::pair<int,unsigned int> tmp
1757
1805
= Utilities::get_integer_at_position (name, 0);
1760
1808
//return fe_name_map.find(name_part)->second->get(QGaussLobatto<1>(tmp.first));
1761
1809
AssertThrow (false, ExcNotImplemented());
1765
1813
AssertThrow (false,ExcNotImplemented());
1771
1819
// hm, if we have come thus far, we
1772
1820
// didn't know what to do with the
1773
1821
// string we got. so do as the docs
1827
1875
pos < name.size();
1828
1876
pos = name.find("^dim"))
1829
1877
name.erase(pos+2, 2);
1831
1879
// Replace all occurences of "^d"
1832
1880
// by using the actual dimension
1833
1881
for (unsigned int pos = name.find("^d");
1834
1882
pos < name.size();
1835
1883
pos = name.find("^d"))
1836
1884
name.at(pos+1) = '0' + dim;
1840
1888
FiniteElement<dim,dim> *fe = internal::get_fe_from_name<dim,dim> (name);
1842
1890
// Make sure the auxiliary function
1977
template <int dim, int spacedim>
1980
compute_projection_from_face_quadrature_points_matrix (const FiniteElement<dim, spacedim> &fe,
1981
const Quadrature<dim-1> &lhs_quadrature,
1982
const Quadrature<dim-1> &rhs_quadrature,
1983
const typename DoFHandler<dim, spacedim>::active_cell_iterator & cell,
1985
FullMatrix<double> &X)
1987
Assert (fe.n_components() == 1, ExcNotImplemented());
1988
Assert (lhs_quadrature.size () > fe.degree, ExcNotGreaterThan (lhs_quadrature.size (), fe.degree));
1992
// build the matrices M and Q
1993
// described in the documentation
1994
FullMatrix<double> M (fe.dofs_per_cell, fe.dofs_per_cell);
1995
FullMatrix<double> Q (fe.dofs_per_cell, rhs_quadrature.size());
1998
// need an FEFaceValues object to evaluate shape function
1999
// values on the specified face.
2000
FEFaceValues <dim> fe_face_values (fe, lhs_quadrature, update_values);
2001
fe_face_values.reinit (cell, face); // setup shape_value on this face.
2003
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2004
for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2005
for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
2006
M(i,j) += fe_face_values.shape_value (i, q) *
2007
fe_face_values.shape_value (j, q) *
2008
lhs_quadrature.weight(q);
2009
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2011
M(i,i) = (M(i,i) == 0 ? 1 : M(i,i));
2016
FEFaceValues <dim> fe_face_values (fe, rhs_quadrature, update_values);
2017
fe_face_values.reinit (cell, face); // setup shape_value on this face.
2019
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
2020
for (unsigned int q=0; q<rhs_quadrature.size(); ++q)
2021
Q(i,q) += fe_face_values.shape_value (i, q) *
2022
rhs_quadrature.weight(q);
2025
FullMatrix<double> M_inverse (fe.dofs_per_cell, fe.dofs_per_cell);
2026
M_inverse.invert (M);
2028
// finally compute the result
2029
X.reinit (fe.dofs_per_cell, rhs_quadrature.size());
2030
M_inverse.mmult (X, Q);
2032
Assert (X.m() == fe.dofs_per_cell, ExcInternalError());
2033
Assert (X.n() == rhs_quadrature.size(), ExcInternalError());
1929
2039
/*-------------- Explicit Instantiations -------------------------------*/
1944
2054
void FETools::compute_block_renumbering (
1945
2055
const FiniteElement<deal_II_dimension>& element,
1946
std::vector<unsigned int>&, std::vector<unsigned int>&_indices);
2056
std::vector<unsigned int>&, std::vector<unsigned int>&_indices, bool);
1948
2058
void FETools::get_interpolation_matrix<deal_II_dimension>
1949
2059
(const FiniteElement<deal_II_dimension> &,
2007
2117
#if deal_II_dimension != 3
2119
void FETools::compute_block_renumbering (
2120
const FiniteElement<deal_II_dimension,deal_II_dimension+1>& element,
2121
std::vector<unsigned int>&, std::vector<unsigned int>&_indices, bool);
2009
2123
void FETools::interpolate<deal_II_dimension,deal_II_dimension+1>
2010
2124
(const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, const Vector<double> &,
2011
2125
const DoFHandler<deal_II_dimension,deal_II_dimension+1> &, Vector<double> &);
2380
2494
const Quadrature<deal_II_dimension> &quadrature,
2381
2495
FullMatrix<double> &I_q);
2497
#if deal_II_dimension != 1
2501
compute_projection_from_face_quadrature_points_matrix (const FiniteElement<deal_II_dimension> &fe,
2502
const Quadrature<deal_II_dimension-1> &lhs_quadrature,
2503
const Quadrature<deal_II_dimension-1> &rhs_quadrature,
2504
const DoFHandler<deal_II_dimension>::active_cell_iterator & cell,
2506
FullMatrix<double> &X);
2385
2511
/*---------------------------- fe_tools.cc ---------------------------*/