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
 int
 saf_multiply_quantity(SAF_ParMode pmode,
                       SAF_Quantity *quantity,                   /* IN[OUT] The quantity which is affected by this operation */
                       SAF_Quantity *multiplier,                 /* What to multiply into QUANTITY */
                       int power                                 /* Number of times to multiply MULTIPLIER into QUANTITY */
                       )
 {
     SAF_ENTER(saf_multiply_quantity, SAF_PRECONDITION_ERROR);
     int         i, recip;
     unsigned    dim_q=(SAF_DIMENSIONLESS_QUANTITY & SS_QUANTITY(quantity)->flags);
     unsigned    dim_m=(SAF_DIMENSIONLESS_QUANTITY & SS_QUANTITY(multiplier)->flags);

     SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("PMODE must be valid"));
     if (!_saf_is_participating_proc(pmode)) SAF_RETURN(-1);
     SAF_REQUIRE(SS_QUANTITY(quantity), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("QUANTITY must be a valid quantity handle"));
     SAF_REQUIRE(SS_QUANTITY(multiplier), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("MULTIPLIER must be a valid quantity handle"));


     /* Determine if Q is the reciprocal of M^POWER */
     recip = (dim_q == dim_m);
     for (i=0; i<SS_MAX_BASEQS && recip; i++)
         if (SS_QUANTITY(quantity)->power[i] != -power*SS_QUANTITY(multiplier)->power[i]) recip=0;

     SAF_DIRTY(quantity, pmode);
     if (recip) {
         /* If Q and M are reciprocals then turn U into a dimensionless quntity. */
         SS_QUANTITY(quantity)->flags |= SAF_DIMENSIONLESS_QUANTITY;

     } else if (dim_q==dim_m) {
         /* If Q and M are both dimensioned quantities (the default) then multiply them in the normal cancelling fasion. If Q
          * and M are both dimensionless quantities then they should have only positive powers and they can be added in the
          * normal fasion (the powers refer to cancelling powers in the numerator and denominator). */
         for (i=0; i<SS_MAX_BASEQS; i++)
             SS_QUANTITY(quantity)->power[i] += power * SS_QUANTITY(multiplier)->power[i];

     } else if (dim_q) {
         /* If Q is dimensionless but M is dimensioned, then set Q to be M and turn off the dimensionless flag. In other words,
          * the powers originally in Q cancel themselves. */
         SS_QUANTITY(quantity)->flags &= ~SAF_DIMENSIONLESS_QUANTITY;
         for (i=0; i<SS_MAX_BASEQS; i++)
             SS_QUANTITY(quantity)->power[i] = power * SS_QUANTITY(multiplier)->power[i];

     } else {
         /* Q is dimensioned but M isn't. Just discard M since it would cancel itself anyway. */
     }

     SAF_LEAVE(SAF_SUCCESS);
 }