Skip to content

Commit 56122cf

Browse files
committed
MAINT: Get rid of caching md variables.
1 parent c0966b5 commit 56122cf

File tree

1 file changed

+27
-29
lines changed

1 file changed

+27
-29
lines changed

Diff for: src/porepy/models/metric.py

+27-29
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from abc import ABC
99
from functools import partial
10+
from typing import Callable
1011

1112
import numpy as np
1213

@@ -16,14 +17,14 @@
1617
class BaseMetric(ABC):
1718
"""Base class for a metric on algebraic variant of mixed-dimensional variables."""
1819

19-
def variable_norm(self, solution: np.ndarray) -> float:
20+
def variable_norm(self, values: np.ndarray) -> float:
2021
"""Base method for measuring the size of physical states (increments, solution etc.)
2122
2223
Parameters:
23-
solution: algebraic respresentation of a mixed-dimensional variable
24+
values: algebraic respresentation of a mixed-dimensional variable
2425
2526
Returns:
26-
float: measure of solution
27+
float: measure of values
2728
2829
"""
2930
raise NotImplementedError("This is an abstract class.")
@@ -36,67 +37,64 @@ class EuclideanMetric(BaseMetric):
3637
e.g. considering errors for each variable and/or each grid separately,
3738
possibly using _l2_norm_cell
3839
39-
We normalize by the size of the solution vector as proxy for domain size.
40+
We normalize by the size of the vector as proxy for domain size.
4041
4142
"""
4243

43-
def variable_norm(self, solution: np.ndarray) -> float:
44+
def variable_norm(self, values: np.ndarray) -> float:
4445
"""Implementation of Euclidean l2 norm of the full vector, scaled by vector size.
4546
4647
Parameters:
47-
solution: algebraic respresentation of a mixed-dimensional variable
48+
values: algebraic respresentation of a mixed-dimensional variable
4849
4950
Returns:
50-
float: measure of solution
51+
float: measure of values
5152
5253
"""
53-
return np.linalg.norm(solution) / np.sqrt(solution.size)
54+
return np.linalg.norm(values) / np.sqrt(values.size)
5455

5556

5657
class LebesgueMetric(BaseMetric):
5758
"""Dimension-consistent Lebesgue metric (blind to physics), but separates dimensions."""
5859

59-
def variable_norm(self, solution: np.ndarray) -> float:
60-
"""Implementation of Lebesgue L2 norm of the physical solution.
60+
equation_system: pp.EquationSystem
61+
"""EquationSystem object for the current model. Normally defined in a mixin class
62+
defining the solution strategy.
63+
64+
"""
65+
volume_integral: Callable[[pp.ad.Operator, list[pp.Grid], int], pp.ad.Operator]
66+
"""General volume integral operator, defined in `pp.BalanceEquation`."""
67+
68+
def variable_norm(self, values: np.ndarray) -> float:
69+
"""Implementation of mixed-dimensional Lebesgue L2 norm of a physical state.
6170
6271
Parameters:
63-
solution: algebraic respresentation of a mixed-dimensional variable
72+
values: algebraic respresentation of a mixed-dimensional variable
6473
6574
Returns:
66-
float: measure of solution
75+
float: measure of values
6776
6877
"""
6978
# Initialize container for collecting separate L2 norms (squarred).
7079
integrals_squarred = []
7180

72-
# Convert algebraic solution vector to mixed dimensional variable
73-
# TODO - The current implementation utilizes the datastructures in place, which is
74-
# not very elegant...the creation of a isolated MixedDimensionalVariable without
75-
# data transfer would be better.
76-
cached_variable_values = self.equation_system.get_variable_values(
77-
iterate_index=0
78-
)
79-
self.equation_system.set_variable_values(solution, iterate_index=0)
80-
81-
# Treat each variable separately - with this separate also dimensions
81+
# Use the equation system to get a view onto mixed-dimensional data structures.
82+
# Compute the L2 norm of each variable separately, automatically taking into
83+
# account volume and specific volume
8284
for variable in self.equation_system.variables:
8385

84-
# Compute square of the L2 norm taking into account volume and specific volume
8586
l2_norm = pp.ad.Function(partial(pp.ad.l2_norm, variable.dim), "l2_norm")
8687
sd = variable.domain
88+
indices = self.equation_system.dofs_of(variable)
89+
ad_values = pp.ad.DenseArray(values[indices])
8790
integral_squarred = np.sum(
88-
self.volume_integral(l2_norm(variable) ** 2, [sd], dim=1).value(
91+
self.volume_integral(l2_norm(ad_values) ** 2, [sd], 1).value(
8992
self.equation_system
9093
)
9194
)
9295

9396
# Collect the L2 norm squared.
9497
integrals_squarred.append(integral_squarred)
9598

96-
# Reset the cached variable values
97-
self.equation_system.set_variable_values(
98-
cached_variable_values, iterate_index=0
99-
)
100-
10199
# Squash all results by employing a consistent L2 approach.
102100
return np.sqrt(np.sum(integrals_squarred))

0 commit comments

Comments
 (0)