# Cmfe overview

## How are comparisons done in VisIt

VisIt's comparisons are delivered through its derived quantity language,
commonly referred to as **Expressions**. This choice of delivery mechanism allows for VisIt's
regular feature set to be interoperable with the comparative techniques.

### Notional example

The primary abstraction for VisIt's comparative techniques is referred to as
a **cross-mesh field evaluation**, or **CMFE**. The CMFE
expressions evaluate a field, **F _{c,D}** from a donor mesh,

**M**, onto a target mesh,

_{D}**M**, to form a new field

_{T}**F**(defined on

_{c,T}**M**). There are multiple options for how to perform the evaluation and they are discussed in subsequent sections. Once

_{T}**F**has been evaluated, it can be directly visualized. More commonly, however, that field will be incorporated into further derived quantities. For example, if

_{c,T}**F**is density defined on

_{c,D}**M**, and

_{D}**F**is density on

_{rho}**M**, then the best visualization is likely of

_{T}**F**, which is the difference in density between

_{c,T}-F_{rho}**M**and

_{D}**M**, modulo evaluation artifacts.

_{T}## Evaluation techniques

There are essentially three distinct flavors of evaluation techniques:

- Position-based evaluation
- Connectivity-based evaluation
- Symmetry-based evaluation

### Position-based evaluation

To evaluate a field **F _{c,D}** from mesh

**M**onto mesh

_{D}**M**, the position-based evaluation technique starts by overlaying the zones of mesh

_{T}**M**onto those of

_{D}**M**. Nodal and zonal variables are then evaluated differently.

_{T}#### Zonal variables

For zonal variables, the new field is constructed one zone at a time.
For each zone **Z _{T,i}** of

**M**, the first step is to calculate

_{T}**P**, which is the center of

_{ZC}**Z**.

_{T,i}**M**is then searched to find the zone that contains the point

_{D}**P**, which we name

_{ZC}**Z**. The value of the field at

_{D,j}**Z**is then assigned to

_{D,j}**Z**. No interpolation is performed. An alternative would be to use weighted averages with a weighting function that reflects the magnitude of volume overlap between the zones. This is not implemented in VisIt.

_{T,i}#### Nodal variables

For nodal variables, the new field is constructed one node at a time.
For each node **N _{T,i}** of

**M**, the mesh

_{T}**M**is searched to find the zone,

_{D}**Z**. that contains

_{D,j}**N**. Trilinear interpolation is performed to evaluate the field exactly at point

_{T,i}**N**. The result of this interpolation is then assigned to

_{T,i}**M**at this node.

_{T}#### Non-overlapping regions

There may be regions of **M _{T}** that do not overlap spatially with

**M**. VisIt needs to assign a value to the field

_{D}**F**for these regions. To handle this case, the position-based evaluation routines force you to enter a second variable, defined on

_{c,T}**M**, that it can used for these non-covered regions. The second variable can be a constant (i.e.

_{T}**0**or

**1e30**) or it can be a normal field defined on

**M**(i.e. "density").

_{T}#### Efficiency of implementation

The VisIt implementation should be relatively efficient. An interval tree is
used to store the bounding box of each zone. This allows for the amortized
search time for a zone to be low. Additionally, in parallel, a data
re-distribution phase attempts to ensure that there is an even number of zones
on each processor (zones may come from either **M _{D}** or

**M**). Inherent to this comment is that VisIt is capable of handling dramatically different decompositions of

_{T}**M**and

_{D}**M**and still performing the evaluation, even when VisIt is in a parallel setting.

_{T}### Connectivity-based evaluation

The connectivity-based evaluation routines are only suitable when **M _{D}**
and

**M**have the same topology: the same number of domains and, for each domain, the same number of zones and nodes. In this case, rather than performing many searches over the zones of

_{T}**M**, the value of

_{D}**F**at some zone or some node K is simply the value of

_{c,T}**F**at that same zone or node. Simplistically, straight array copies are made from

_{c,D}**M**to

_{D}**M**.

_{T}### Symmetry-based evaluation

For the symmetry-based evaluations, the donor mesh, **M _{D}**, and the target
mesh,

**M**, are the same mesh,

_{T}**M**. However,

**M**must be transformed in some way to do the comparison. The supported symmetry-based evaluations are:

- Reflect
**M**across a plane - Reflect
**M**across a point - Transform
**M**using an arbitrary 3x3 matrix.

For each of the symmetry-based evaluations, **M** is reflected to form some **M'**,
and the evaluation from **M'** onto **M** is done using the position based evaluation
techniques.

## Expression Code

In this section, we give the syntax for the VisIt expression language for employing the cross-mesh field evaluations. Please note that there is a wizard located in the GUI under Controls->Data Level Comparisons that sets up CMFE expressions automatically. This page describes the syntax it follows, in case you want to "do it yourself".

### pos_cmfe

The position-based evaluation method to evaluate **p** from file **a.00000**
with a default value of **0** onto the mesh **mesh_3d** is:

```
pos_cmfe(<a.00000:p>, mesh_3d, 0)
```

### conn_cmfe

The connectivity-based evaluation method to evaluate **p** from file **a.00000**
onto the mesh **mesh_3d** is:

```
conn_cmfe(<a.00000:p>, mesh_3d)
```

### Differencing with conn_cmfe and pos_cmfe

Note that the two equations above simply evaluate **p** from another file
onto the mesh **mesh_3d** of the currently open file.
It does not look at the differences. This could be accomplished with:

```
p - conn_cmfe(<a.00000:p>, mesh_3d)
```

(This assumes that the currently open file also used the name **p** for the
variable to difference with.)

The symmetry-based evaluation methods described in the following subsections automatically perform the differencing described in the expression above.

### {symm_plane}

The syntax to reflect the variable **p** across a plane defined by the
normal **(Nx, Ny, Nz)** and the origin **(Ox, Oy, Oz)** and then give
the difference is:

```
symn_plane(p, [Nx, Ny, Nz, Ox, Oy, Oz])
```

To be explicitly clear, this expression **is** giving a difference.
So a data set that had perfect symmetry across a plane would
yield a constant **0** for this expression.

### symm_point

The syntax to reflect the variable **p** around the point **(Px, Py, Pz)** and
then calculate the difference is:

```
symn_point(p, [Px, Py, Pz])
```

### symm_transform

Consider transformations that can be captured by 3x3 matrics. For a point
**(X, Y, Z)**, we can consider matrices such as:

```
```

( T00 & T10 T20 )
(X, Y, Z) * ( T01 & T11 T21 )
( T02 & T12 T22 )
= (T00*X + T01*Y + T02*Z, ...)

```
```

The syntax to transform the variable **p** by this matrix and produce the
differences is:

```
symn_transform(p, [T00, T01, T02, T10, T11, T12, T20, T21, T22])
```

### More complex expressions

Additional syntax can be used to specify time states of a time-varying database. Further, because the functionality takes place inside the expression language, an arbitrary number of databases can be considered. Their analysis can be combined through multiple uses of the ``if" expression, which does if-then-else.

## Examples

- Simple example of using a CMFE to calculate the difference between two datasets.
- How to calculate an average across time.
- Use of CMFEs in python to calculate a diff.