MFEM  v3.3.2
Finite element discretization library
linearform.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Implementation of class LinearForm
13 
14 #include "fem.hpp"
15 
16 namespace mfem
17 {
18 
20 {
21  DeltaLFIntegrator *maybe_delta =
22  dynamic_cast<DeltaLFIntegrator *>(lfi);
23  if (!maybe_delta || !maybe_delta->IsDelta())
24  {
25  dlfi.Append(lfi);
26  }
27  else
28  {
29  dlfi_delta.Append(maybe_delta);
30  }
31 }
32 
34 {
35  blfi.Append (lfi);
36 }
37 
39 {
40  flfi.Append(lfi);
41  flfi_marker.Append(NULL); // NULL -> all attributes are active
42 }
43 
45  Array<int> &bdr_attr_marker)
46 {
47  flfi.Append(lfi);
48  flfi_marker.Append(&bdr_attr_marker);
49 }
50 
52 {
53  Array<int> vdofs;
54  ElementTransformation *eltrans;
55  Vector elemvect;
56 
57  int i;
58 
59  Vector::operator=(0.0);
60 
61  if (dlfi.Size())
62  for (i = 0; i < fes -> GetNE(); i++)
63  {
64  fes -> GetElementVDofs (i, vdofs);
65  eltrans = fes -> GetElementTransformation (i);
66  for (int k=0; k < dlfi.Size(); k++)
67  {
68  dlfi[k]->AssembleRHSElementVect(*fes->GetFE(i), *eltrans, elemvect);
69  AddElementVector (vdofs, elemvect);
70  }
71  }
72 
73  AssembleDelta();
74 
75  if (blfi.Size())
76  for (i = 0; i < fes -> GetNBE(); i++)
77  {
78  fes -> GetBdrElementVDofs (i, vdofs);
79  eltrans = fes -> GetBdrElementTransformation (i);
80  for (int k=0; k < blfi.Size(); k++)
81  {
82  blfi[k]->AssembleRHSElementVect(*fes->GetBE(i), *eltrans, elemvect);
83  AddElementVector (vdofs, elemvect);
84  }
85  }
86 
87  if (flfi.Size())
88  {
90  Mesh *mesh = fes->GetMesh();
91 
92  // Which boundary attributes need to be processed?
93  Array<int> bdr_attr_marker(mesh->bdr_attributes.Size() ?
94  mesh->bdr_attributes.Max() : 0);
95  bdr_attr_marker = 0;
96  for (int k = 0; k < flfi.Size(); k++)
97  {
98  if (flfi_marker[k] == NULL)
99  {
100  bdr_attr_marker = 1;
101  break;
102  }
103  Array<int> &bdr_marker = *flfi_marker[k];
104  MFEM_ASSERT(bdr_marker.Size() == bdr_attr_marker.Size(),
105  "invalid boundary marker for boundary face integrator #"
106  << k << ", counting from zero");
107  for (int i = 0; i < bdr_attr_marker.Size(); i++)
108  {
109  bdr_attr_marker[i] |= bdr_marker[i];
110  }
111  }
112 
113  for (i = 0; i < mesh->GetNBE(); i++)
114  {
115  const int bdr_attr = mesh->GetBdrAttribute(i);
116  if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
117 
118  tr = mesh->GetBdrFaceTransformations(i);
119  if (tr != NULL)
120  {
121  fes -> GetElementVDofs (tr -> Elem1No, vdofs);
122  for (int k = 0; k < flfi.Size(); k++)
123  {
124  if (flfi_marker[k] &&
125  (*flfi_marker[k])[bdr_attr-1] == 0) { continue; }
126 
127  flfi[k] -> AssembleRHSElementVect (*fes->GetFE(tr -> Elem1No),
128  *tr, elemvect);
129  AddElementVector (vdofs, elemvect);
130  }
131  }
132  }
133  }
134 }
135 
136 void LinearForm::Update(FiniteElementSpace *f, Vector &v, int v_offset)
137 {
138  fes = f;
139  NewDataAndSize((double *)v + v_offset, fes->GetVSize());
140  ResetDeltaLocations();
141 }
142 
144 {
145  if (dlfi_delta.Size() == 0) { return; }
146 
147  if (!HaveDeltaLocations())
148  {
149  int sdim = fes->GetMesh()->SpaceDimension();
150  Vector center;
151  DenseMatrix centers(sdim, dlfi_delta.Size());
152  for (int i = 0; i < centers.Width(); i++)
153  {
154  centers.GetColumnReference(i, center);
155  dlfi_delta[i]->GetDeltaCenter(center);
156  MFEM_VERIFY(center.Size() == sdim,
157  "Point dim " << center.Size() <<
158  " does not match space dim " << sdim);
159  }
160  fes->GetMesh()->FindPoints(centers, dlfi_delta_elem_id, dlfi_delta_ip);
161  }
162 
163  Array<int> vdofs;
164  Vector elemvect;
165  for (int i = 0; i < dlfi_delta.Size(); i++)
166  {
167  int elem_id = dlfi_delta_elem_id[i];
168  // The delta center may be outside of this sub-domain, or
169  // (Par)Mesh::FindPoints() failed to find this point:
170  if (elem_id < 0) { continue; }
171 
172  const IntegrationPoint &ip = dlfi_delta_ip[i];
174  Trans.SetIntPoint(&ip);
175 
176  fes->GetElementVDofs(elem_id, vdofs);
177  dlfi_delta[i]->AssembleDeltaElementVect(*fes->GetFE(elem_id), Trans,
178  elemvect);
179  AddElementVector(vdofs, elemvect);
180  }
181 }
182 
184 {
185  int k;
186  for (k=0; k < dlfi_delta.Size(); k++) { delete dlfi_delta[k]; }
187  for (k=0; k < dlfi.Size(); k++) { delete dlfi[k]; }
188  for (k=0; k < blfi.Size(); k++) { delete blfi[k]; }
189  for (k=0; k < flfi.Size(); k++) { delete flfi[k]; }
190 }
191 
192 }
int Size() const
Logical size of the array.
Definition: array.hpp:110
int GetVSize() const
Definition: fespace.hpp:163
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
Definition: mesh.hpp:855
void NewDataAndSize(double *d, int s)
Set the Vector data and size, deleting the old data, if owned.
Definition: vector.hpp:101
int GetNBE() const
Returns number of boundary elements.
Definition: mesh.hpp:617
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Definition: fespace.cpp:133
void Assemble()
Assembles the linear form i.e. sums over all domain/bdr integrators.
Definition: linearform.cpp:51
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:52
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
int Size() const
Returns the size of the vector.
Definition: vector.hpp:113
Abstract base class LinearFormIntegrator.
Definition: lininteg.hpp:22
Vector & operator=(const double *v)
Copy Size() entries from v.
Definition: vector.cpp:117
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:136
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition: array.cpp:108
void AddBdrFaceIntegrator(LinearFormIntegrator *lfi)
Adds new Boundary Face Integrator.
Definition: linearform.cpp:38
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
Definition: mesh.cpp:717
void AddBoundaryIntegrator(LinearFormIntegrator *lfi)
Adds new Boundary Integrator.
Definition: linearform.cpp:33
bool IsDelta() const
Returns true if the derived class instance uses a delta coefficient.
Definition: lininteg.hpp:70
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add (element) subvector to the vector.
Definition: vector.cpp:550
int SpaceDimension() const
Definition: mesh.hpp:642
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i'th element.
Definition: fespace.hpp:205
void AddDomainIntegrator(LinearFormIntegrator *lfi)
Adds new Domain Integrator.
Definition: linearform.cpp:19
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition: mesh.hpp:172
void GetColumnReference(int c, Vector &col)
Definition: densemat.hpp:243
Abstract class for integrators that support delta coefficients.
Definition: lininteg.hpp:47
void AssembleDelta()
Assembles delta functions of the linear form.
Definition: linearform.cpp:143
Class for integration point with weight.
Definition: intrules.hpp:25
~LinearForm()
Destroys linear form.
Definition: linearform.cpp:183
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
Definition: fespace.cpp:1171
virtual int FindPoints(DenseMatrix &point_mat, Array< int > &elem_ids, Array< IntegrationPoint > &ips, bool warn=true, InverseElementTransformation *inv_trans=NULL)
Find the ids of the elements that contain the given points, and their corresponding reference coordin...
Definition: mesh.cpp:8539
Vector data type.
Definition: vector.hpp:41
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement for the i'th boundary element.
Definition: fespace.cpp:1406