public static double CalculateError(IFiniteElementSpace feSpace, Func <double, double, double> exactSolution, FiniteElementVectorField solution) { double squareError = 0; foreach (var element in feSpace.FiniteElements) { Func <Vector2, double> error = v => { double u0 = exactSolution(v.x, v.y), uh0 = 0; foreach (var node in element.Nodes) { uh0 += node.Phi(v) * solution.GetValueAt(node.Vertex, 0); } return((u0 - uh0) * (u0 - uh0)); }; squareError += quadrature.Integrate(error, element.Triangle); } return(Math.Sqrt(squareError)); }
public FiniteElementScalarField(IFiniteElementSpace finiteElementSpace, IEnumerable <double> values) { this.finiteElementSpace = finiteElementSpace; int n = finiteElementSpace.Vertices.Count; valueByVertex = new Dictionary <Vertex, double>(n); int valueCount = 0; var valueEnumerator = values.GetEnumerator(); foreach (var vertex in finiteElementSpace.Vertices) { valueEnumerator.MoveNext(); var value = valueEnumerator.Current; valueByVertex.Add(vertex, value); valueCount++; } if (valueCount != n) { throw new ArgumentException($"The number of values ({valueCount}) does not match the number of vertices ({n})."); } }
public Problem(IFiniteElementSpace finiteElementSpace, Dictionary <int, IVectorField> boundaryConditions, BilinearForm bilinearForm, IVectorField rightHandSide, ISolver solver = null, IQuadrature quadrature = null) { this.finiteElementSpace = finiteElementSpace; this.boundaryConditions = boundaryConditions; this.bilinearForm = bilinearForm; this.rightHandSide = rightHandSide; var dim = rightHandSide.Dimension; var mismatch = boundaryConditions.Values .Any(condition => condition.Dimension != dim); if (mismatch) { throw new ArgumentException("Dimension mismatched."); } // TODO: Validate bilinear form. this.solver = solver ?? new ConjugateGradient(1e-6); this.quadrature = quadrature ?? new GaussianQuadrature(); }