Skip to content

Commit ae5ab1c

Browse files
Added Mathematical operations doc page (#865)
* Added Mathematical operations doc page * Moved scoping related code to the end * minor page formatting, style check * Apply suggestions from code review Co-authored-by: JennaPaikowsky <[email protected]> * comments-related suggestions from review --------- Co-authored-by: JennaPaikowsky <[email protected]>
1 parent 7b5e482 commit ae5ab1c

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# noqa: D400
2+
"""
3+
.. _ref_math_operators_example:
4+
5+
Mathematical Operations
6+
~~~~~~~~~~~~~~~~~~~~~~~
7+
8+
DPF provides operators for implementing mathematical operations,
9+
ranging from addition and multiplication to FFT and QR solving.
10+
11+
For a complete list, see :ref:`ref_dpf_operators_reference`, under the math section.
12+
13+
"""
14+
15+
# Import the necessary modules
16+
import ansys.dpf.core as dpf
17+
18+
###############################################################################
19+
# Addition
20+
# ~~~~~~~~
21+
22+
# Initialize Fields
23+
num_entities = 2
24+
field1 = dpf.Field(nentities=2)
25+
field2 = dpf.Field(nentities=2)
26+
27+
# By default, Fields contain 3d vectors.
28+
# So with three entities we need nine values.
29+
field1.data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
30+
field2.data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
31+
32+
field1.scoping.ids = range(num_entities)
33+
field2.scoping.ids = range(num_entities)
34+
###############################################################################
35+
# Once the fields are ready, we can instantiate an operator.
36+
add_op = dpf.operators.math.add(field1, field2)
37+
38+
###############################################################################
39+
# Finally, we use eval() to compute and retrieve the result.
40+
field3 = add_op.eval()
41+
42+
# = [[2. 4. 6.] [8. 10. 12.]]
43+
print(field3.data)
44+
45+
###############################################################################
46+
# Dot product
47+
# ~~~~~~~~~~~
48+
dot_op = dpf.operators.math.generalized_inner_product(field1, field2)
49+
50+
# (1. * 1.) + (2. * 2.) + (3. * 3.) = 14.
51+
# (4. * 4.) + (5. * 5.) + (6. * 6.) = 77.
52+
field3 = dot_op.eval()
53+
print(field3.data)
54+
55+
56+
###############################################################################
57+
# Power
58+
# ~~~~~
59+
field = dpf.Field(nentities=1)
60+
field1.data = [1.0, 2.0, 3.0]
61+
field1.scoping.ids = [1]
62+
63+
pow_op = dpf.operators.math.pow(field1, 3.0)
64+
65+
# [1. 8. 27.]
66+
field3 = pow_op.eval()
67+
print(field3.data)
68+
69+
70+
###############################################################################
71+
# L2 norm
72+
# ~~~~~~~
73+
field1.data = [16.0, -8.0, 2.0]
74+
norm_op = dpf.operators.math.norm(field1)
75+
76+
# [ 18. ]
77+
field3 = norm_op.eval()
78+
print(field3.data)
79+
80+
81+
###############################################################################
82+
# Accumulate
83+
# ~~~~~~~~~~
84+
# First we define fields. By default, fields represent 3D vectors
85+
# so one elementary data is a 3D vector.
86+
# The optional ponderation field is a field which takes one value per entity,
87+
# so we need to change its dimensionality (1D).
88+
num_entities = 3
89+
input_field = dpf.Field(nentities=num_entities)
90+
ponderation_field = dpf.Field(num_entities)
91+
ponderation_field.dimensionality = dpf.Dimensionality([1])
92+
93+
input_field.scoping.ids = range(num_entities)
94+
ponderation_field.scoping.ids = range(num_entities)
95+
96+
###############################################################################
97+
# Fill fields with data.
98+
# Add nine values because there are three entities.
99+
input_field.data = [-2.0, 2.0, 4.0, -5.0, 0.5, 1.0, 7.0, 3.0, -3.0]
100+
###############################################################################
101+
# Three weights, one per entity.
102+
ponderation_field.data = [0.5, 2.0, 0.5]
103+
104+
###############################################################################
105+
# Retrieve the result.
106+
acc = dpf.operators.math.accumulate(fieldA=input_field, ponderation=ponderation_field)
107+
output_field = acc.outputs.field()
108+
109+
# (-2.0 * 0.5) + (-5.0 * 2.0) + (7.0 * 0.5) = -7.5
110+
# (2.0 * 0.5) + (0.5 * 2.0) + (3.0 * 0.5) = 3.5
111+
# (4.0 * 0.5) + (1.0 * 2.0) + (-3.0 * 0.5) = 2.5
112+
print(output_field.data)
113+
114+
###############################################################################
115+
# With scoping
116+
# ~~~~~~~~~~~~
117+
field1.data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
118+
field2.data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
119+
120+
###############################################################################
121+
# Next, we need to provide information about the scoping.
122+
# DPF needs to know the IDs of the data we just provided,
123+
# so that it can apply an operator on a subset of the original data.
124+
#
125+
# By providing these integers we only select the data with an ID in common.
126+
# Here we are selecting the third elementary data of the first field,
127+
# and the first elementary data of the second field,
128+
# Other elementary data is not taken into account when using an operator that needs two operands.
129+
field1.scoping.ids = [1, 2, 3]
130+
field2.scoping.ids = [3, 4, 5]
131+
132+
add_op = dpf.operators.math.add(field1, field2)
133+
field3 = add_op.eval()
134+
135+
# Only the third entity was changed
136+
# because it is the only operator where two operands were provided.
137+
print(field3.data)
138+
# [[8. 10. 12.]]
139+
print(field3.get_entity_data_by_id(3))
140+
141+
###############################################################################
142+
# Dot product
143+
144+
dot_op = dpf.operators.math.generalized_inner_product(field1, field2)
145+
146+
# We obtain zeros for IDs where there could not be two operands.
147+
# (7. * 1.) + (8. * 2.) + (9. * 3.) = 50.
148+
# [0. 0. 50. 0. 0.]
149+
field3 = dot_op.eval()
150+
print(field3.data)

0 commit comments

Comments
 (0)