-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFillPartialArrays.py
More file actions
154 lines (118 loc) · 6.13 KB
/
FillPartialArrays.py
File metadata and controls
154 lines (118 loc) · 6.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies.
# SPDX-FileContributor: Romain Baville, Martin Lemay
from typing_extensions import Self
from typing import Union, Any
from geos.utils.Logger import logging, Logger, getLogger
from geos.mesh.utils.arrayModifiers import fillPartialAttributes
from geos.mesh.utils.arrayHelpers import isAttributeInObject
from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet
__doc__ = """
Fill partial attributes of the input mesh with constant values per component.
Input mesh is vtkMultiBlockDataSet and attributes to fill must be partial.
The list of filling values per attribute is given by a dictionary.
Its keys are the attribute names and its items are the list of filling values for each component.
If the list of filling value is None, attributes are filled with the same constant value for each component;
0 for uint data, -1 for int data and nan for float data.
To use a handler of yours for the logger, set the variable 'speHandler' to True and add it to the filter
with the member function addLoggerHandler.
To use it:
.. code-block:: python
from geos.mesh.processing.FillPartialArrays import FillPartialArrays
# Filter inputs.
multiBlockDataSet: vtkMultiBlockDataSet
dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ]
# Optional inputs.
speHandler: bool
# Instantiate the filter.
filter: FillPartialArrays = FillPartialArrays( multiBlockDataSet, dictAttributesValues, speHandler )
# Set the handler of yours (only if speHandler is True).
yourHandler: logging.Handler
filter.addLoggerHandler( yourHandler )
# Do calculations.
filter.applyFilter()
"""
loggerTitle: str = "Fill Partial Attribute"
class FillPartialArrays:
def __init__(
self: Self,
multiBlockDataSet: vtkMultiBlockDataSet,
dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ],
speHandler: bool = False,
) -> None:
"""Fill partial attributes with constant value per component.
If the list of filling values for an attribute is None, it will filled with the default value for each component:
0 for uint data.
-1 for int data.
nan for float data.
Args:
multiBlockDataSet (vtkMultiBlockDataSet): The mesh where to fill the attribute.
dictAttributesValues (dict[str, Any]): The dictionary with the attribute to fill as keys and the list of filling values as items.
speHandler (bool, optional): True to use a specific handler, False to use the internal handler.
Defaults to False.
"""
self.multiBlockDataSet: vtkMultiBlockDataSet = multiBlockDataSet
self.dictAttributesValues: dict[ str, Union[ list[ Any ], None ] ] = dictAttributesValues
# Logger.
self.logger: Logger
if not speHandler:
self.logger = getLogger( loggerTitle, True )
else:
self.logger = logging.getLogger( loggerTitle )
self.logger.setLevel( logging.INFO )
def setLoggerHandler( self: Self, handler: logging.Handler ) -> None:
"""Set a specific handler for the filter logger.
In this filter 4 log levels are use, .info, .error, .warning and .critical, be sure to have at least the same 4 levels.
Args:
handler (logging.Handler): The handler to add.
"""
if not self.logger.hasHandlers():
self.logger.addHandler( handler )
else:
self.logger.warning(
"The logger already has an handler, to use yours set the argument 'speHandler' to True during the filter initialization."
)
def applyFilter( self: Self ) -> bool:
"""Create a constant attribute per region in the mesh.
Returns:
boolean (bool): True if calculation successfully ended, False otherwise.
"""
self.logger.info( f"Apply filter { self.logger.name }." )
for attributeName in self.dictAttributesValues:
self._setPieceRegionAttribute( attributeName )
if self.onPoints is None:
self.logger.error( f"{ attributeName } is not in the mesh." )
self.logger.error( f"The attribute { attributeName } has not been filled." )
self.logger.error( f"The filter { self.logger.name } failed." )
return False
if self.onBoth:
self.logger.error(
f"Their is two attribute named { attributeName }, one on points and the other on cells. The attribute must be unique."
)
self.logger.error( f"The attribute { attributeName } has not been filled." )
self.logger.error( f"The filter { self.logger.name } failed." )
return False
if not fillPartialAttributes( self.multiBlockDataSet,
attributeName,
onPoints=self.onPoints,
listValues=self.dictAttributesValues[ attributeName ],
logger=self.logger ):
self.logger.error( f"The filter { self.logger.name } failed." )
return False
self.logger.info( f"The filter { self.logger.name } succeed." )
return True
def _setPieceRegionAttribute( self: Self, attributeName: str ) -> None:
"""Set the attribute self.onPoints and self.onBoth.
self.onPoints is True if the region attribute is on points, False if it is on cells, None otherwise.
self.onBoth is True if a region attribute is on points and on cells, False otherwise.
Args:
attributeName (str): The name of the attribute to verify.
"""
self.onPoints: Union[ bool, None ] = None
self.onBoth: bool = False
if isAttributeInObject( self.multiBlockDataSet, attributeName, False ):
self.onPoints = False
if isAttributeInObject( self.multiBlockDataSet, attributeName, True ):
if self.onPoints is False:
self.onBoth = True
self.onPoints = True