@@ -39,82 +39,14 @@ GradNonLinearForm::GradNonLinearForm(ParFiniteElementSpace *_vfes, IntegrationRu
39
39
40
40
void GradNonLinearForm::Mult (const ParGridFunction *Up, Vector &y) {
41
41
Vector x;
42
-
43
- #ifdef _GPU_
44
- // TestNonLinearForm::setToZero_gpu(y,y.Size()); already done in gradient.cpd
45
- x.UseDevice (true );
46
- if (fnfi.Size ()) {
47
- x.NewMemoryAndSize (Up->GetMemory (), vfes->GetNDofs () * num_equation, false );
48
- Mult_gpu (x, y);
49
- }
50
- #else
51
42
const double *data = Up->GetData ();
43
+
44
+ // NB: Setting x here accounts for the fact that the space Up lives
45
+ // in is different from the space of the gradient.
52
46
x.SetSize (vfes->GetNDofs () * num_equation * dim);
53
47
x = 0 .;
54
48
for (int i = 0 ; i < vfes->GetNDofs () * num_equation; i++) x (i) = data[i];
55
- ParNonlinearForm::Mult (x, y);
56
- #endif
57
- }
58
-
59
- #ifdef _GPU_
60
- void GradNonLinearForm::Mult_gpu (const Vector &x, Vector &y) {
61
- // INTEGRATION SHARED FACES
62
- const Vector &px = Prolongate (x);
63
-
64
- const int dofs = vfes->GetNDofs ();
65
-
66
- // Terms over shared interior faces in parallel.
67
- ParFiniteElementSpace *pfes = ParFESpace ();
68
- ParMesh *pmesh = pfes->GetParMesh ();
69
- FaceElementTransformations *tr;
70
- const FiniteElement *fe1, *fe2;
71
- Array<int > vdofs1, vdofs2;
72
- Vector el_x, el_y;
73
- el_x.UseDevice (true );
74
- el_y.UseDevice (true );
75
-
76
- // if (bfnfi.Size()==0) y.HostReadWrite();
77
- X.MakeRef (aux1, 0 ); // aux1 contains P.x
78
- X.ExchangeFaceNbrData ();
79
- const int n_shared_faces = pmesh->GetNSharedFaces ();
80
- for (int i = 0 ; i < n_shared_faces; i++) {
81
- tr = pmesh->GetSharedFaceTransformations (i, true );
82
- int Elem2NbrNo = tr->Elem2No - pmesh->GetNE ();
83
49
84
- fe1 = pfes->GetFE (tr->Elem1No );
85
- fe2 = pfes->GetFaceNbrFE (Elem2NbrNo);
86
-
87
- pfes->GetElementVDofs (tr->Elem1No , vdofs1);
88
- pfes->GetFaceNbrElementVDofs (Elem2NbrNo, vdofs2);
89
-
90
- el_x.SetSize (vdofs1.Size () + vdofs2.Size ());
91
- X.GetSubVector (vdofs1, el_x.GetData ());
92
- X.FaceNbrData ().GetSubVector (vdofs2, el_x.GetData () + vdofs1.Size ());
93
-
94
- const int elDof1 = fe1->GetDof ();
95
- const int elDof2 = fe2->GetDof ();
96
- for (int k = 0 ; k < fnfi.Size (); k++) {
97
- fnfi[k]->AssembleFaceVector (*fe1, *fe2, *tr, el_x, el_y);
98
- // y.AddElementVector(vdofs1, el_y.GetData());
99
- GradNonLinearForm::IndexedAddToGlobalMemory (vdofs1, y, el_y, dofs, elDof1, num_equation, dim);
100
- }
101
- }
102
- }
103
-
104
- void GradNonLinearForm::IndexedAddToGlobalMemory (const Array<int > &vdofs, Vector &y, const Vector &el_y, const int &dof,
105
- const int &elDof, const int &num_equation, const int &dim) {
106
- double *dy = y.ReadWrite ();
107
- const double *d_ely = el_y.Read ();
108
- auto d_vdofs = vdofs.Read ();
109
-
110
- MFEM_FORALL (i, elDof, {
111
- const int index = d_vdofs[i];
112
- for (int eq = 0 ; eq < num_equation; eq++) {
113
- for (int d = 0 ; d < dim; d++) {
114
- dy[index + eq * dof + d * num_equation * dof] += d_ely[i + eq * elDof + d * num_equation * elDof];
115
- }
116
- }
117
- });
50
+ // After setting x as above, base class Mult does the right thing
51
+ ParNonlinearForm::Mult (x, y);
118
52
}
119
-
120
- #endif // _GPU_
0 commit comments