Application Center - Maplesoft

App Preview:

Pi Theorem Application

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


 

Image 

Π Theorem for Finding Dimensionless Groups for a Physical System 

Lee R. Partin 

Copyright 2008, L R Partin 

lpartin@chartertn.net 

 

The Typesetting:-mrow(Typesetting:-mi( theorem provides information about the relationship of physical parameters within a physical system.   

 

Suppose you have a physical system that is determined by five parameters such that Typesetting:-mrow(Typesetting:-mi(.  The Typesetting:-mrow(Typesetting:-mi( Theorem determines the number of dimensionless groups composed of the five parameters that are required to restate the equation.  Suppose that three groups are required.  The new equation is Typesetting:-mrow(Typesetting:-mi(. 

 

Thomas Szirtes provided detailed procedures to determine the Typesetting:-mrow(Typesetting:-mi( groups in his book "Applied Dimensional Analysis and Modeling," McGraw-Hill, (1998), ISBN 0-07-062811-4.  See chapters 7 and 8 for the methodology.  The procedures were programmed in Maple using its Units module.  The textbook has numerous examples for applying the Π Theorem.  The book is very good at explaining the application of the Π theorem to physical systems. 

 

Restart 

Restart Maple to initialize the work space. 

> restart;
 

Module Programming 

The Units module provides the needed capability to handle the Pi theorem methodology.  A module called GeneratePiTheorem applies Units in its programming of the Pi methodology. 

Initialization 

Initializing the Units module: 

> with(Units);
 

[AddBaseUnit, AddDimension, AddSystem, AddUnit, Converter, GetDimension, GetDimensions, GetSystem, GetSystems, GetUnit, GetUnits, HasDimension, HasSystem, HasUnit, Natural, RemoveDimension, RemoveSyst...
[AddBaseUnit, AddDimension, AddSystem, AddUnit, Converter, GetDimension, GetDimensions, GetSystem, GetSystems, GetUnit, GetUnits, HasDimension, HasSystem, HasUnit, Natural, RemoveDimension, RemoveSyst...
[AddBaseUnit, AddDimension, AddSystem, AddUnit, Converter, GetDimension, GetDimensions, GetSystem, GetSystems, GetUnit, GetUnits, HasDimension, HasSystem, HasUnit, Natural, RemoveDimension, RemoveSyst...
[AddBaseUnit, AddDimension, AddSystem, AddUnit, Converter, GetDimension, GetDimensions, GetSystem, GetSystems, GetUnit, GetUnits, HasDimension, HasSystem, HasUnit, Natural, RemoveDimension, RemoveSyst...
(2.1.1)
 

Module 

The Pi theorem method is programmed in a module that is created within a routine.  The k 

> GeneratePiTheorem:=proc(f::`name`) description "generate a module for doing the calcs";
f:=module()
 description "application module for Pi theorem definition of dimensionless numbers";
 local NumberAcceptedFundamentals, NumberAcceptedParams, NumberUnitlessParams;
 export ParamNames, ParamTypes, Initialize, degrees, Check, fundamentals, MatrixUnit,
        MatrixFundamentals, MatrixParams, UnitlessParams, FindPiGroups, Groups,
        GroupsDef, GroupsLabel, PrintPiGroups, ExcludedFundamentals, Exclude;
 ParamNames:=table();
 ParamTypes:=table();
 MatrixFundamentals:=table();
 MatrixParams:=table();
 UnitlessParams:=table();
 ExcludedFundamentals:=[];
 Groups:=0;
 NumberAcceptedFundamentals:=0;
 NumberAcceptedParams:=0;
 NumberUnitlessParams:=0;
 Initialize:=proc() description "initialize data for the Pi therorm";
   local inputs, i, j;
   if nargs<>1 then error "one input is required; it is a set of physical parameters" fi;
   if type(args[1],`list`)=false then error "input a list of physical parameters" fi;
   inputs:=convert(args[1],`list`);
   ParamNames:=[seq(convert(lhs(inputs[i]),`string`),i=1..nops(inputs))];
   ParamTypes:=[seq(rhs(inputs[i]),i=1..nops(inputs))];
   fundamentals:=[Units:-GetDimensions(base)];
   degrees:=array(1..nops(fundamentals),1..nops(ParamTypes));
   for i from 1 to nops(fundamentals) do
     for j from 1 to nops(ParamTypes) do
        if ParamTypes[j]<>1 then
          degrees[i,j]:=degree(Units:-GetDimension(ParamTypes[j]),fundamentals[i])
        else
          degrees[i,j]:=0;
        fi;
     end do;
   end do;
   j:=0;
   for i from 1 to nops(ParamTypes) do
     if ParamTypes[i]=1 then
        j:=j+1;
        UnitlessParams[j]:=ParamNames[i];
     fi;
   end do;
   NumberUnitlessParams:=j;
   if j>0 then UnitlessParams:=convert(UnitlessParams,`list`) fi;
   RETURN();
 end proc:
 Exclude:=proc(ExcludeList::`list`)
   description "enter list of fundamentals to exclude from analysis";
   ExcludedFundamentals:=ExcludeList;
 end proc:
 Check:=proc() description "check the parameter specifications" ;
   local i, j, rowCounts, errorCode, columnCounts, acceptedParams, acceptedFundamentals,
         k;
   errorCode:=0;
   for i from 1 to nops(fundamentals) do
     rowCounts[i]:=0;
     for j from 1 to nops(ParamTypes) do
       if degrees[i,j]<>0 then rowCounts[i]:=rowCounts[i]+1 fi
     end do;
   end do;
   for j from 1 to nops(ParamTypes) do
     columnCounts[j]:=0;
     for i from 1 to nops(fundamentals) do
       if degrees[i,j]<>0 then columnCounts[j]:=columnCounts[j]+1 fi
     end do;
   end do;
   # check for a fundamentals row with only one entry
   for i from 1 to nops(fundamentals) do
     if rowCounts[i]=1 then
       printf("Fundamental unit ( %s ) has only one entry within the groups.  You must drop the parameter containing it or add another physical parameter with that fundamental unit.", fundamentals[i]);
       error "there is a row with only one entry for the fundamental unit";
     fi;
   end do;
   # accept the physical parameters that contain fundamental units
   j:=0;
   #printf("accepted parameters: \n");
   for i from 1 to nops(ParamTypes) do
     if columnCounts[i]>0 then
        j:=j+1;
        acceptedParams[j]:=i;
        MatrixParams[j]:=ParamNames[i];
   #     printf("  %s  \n",ParamNames[i]);         
     fi;
   end do;
   MatrixParams:=convert(MatrixParams,`list`);
   #printf("  %s  \n",ParamNames[1]);
   NumberAcceptedParams:=j;
   k:=0;
   #printf("accepted fundamental units: \n");
   for i from 1 to nops(fundamentals) do
     if rowCounts[i]>1 and not member(fundamentals[i],ExcludedFundamentals) then
       k:=k+1;
       acceptedFundamentals[k]:=i;
       MatrixFundamentals[k]:=fundamentals[i];
   #    printf("  %s  \n",fundamentals[i]);
     fi;
   end do;
   MatrixFundamentals:=convert(MatrixFundamentals,`list`);
   NumberAcceptedFundamentals:=k;
   MatrixUnit:=array(1..NumberAcceptedFundamentals,1..NumberAcceptedParams);
   for i from 1 to NumberAcceptedFundamentals do
     for j from 1 to NumberAcceptedParams do
       MatrixUnit[i,j]:=degrees[acceptedFundamentals[i],acceptedParams[j]]
     end do;
   end do;
   if NumberUnitlessParams>0 then
     RETURN(UnitMatrix=eval(MatrixUnit),Fundamentals=MatrixFundamentals,
            Parameters=MatrixParams, UnitlessParameters=UnitlessParams)
   else
     RETURN(UnitMatrix=eval(MatrixUnit),Fundamentals=MatrixFundamentals,
            Parameters=MatrixParams, UnitlessParameters=0)
   fi;    
 end proc:
 FindPiGroups:=proc() description "find the dimensionless groups (Pi groups)";
   local i, j, k, A, B, C, det, Delta;
   A:=Matrix(NumberAcceptedFundamentals);
   for i from 1 to NumberAcceptedFundamentals do
     for j from 1 to NumberAcceptedFundamentals do
       k:=j + NumberAcceptedParams - NumberAcceptedFundamentals;
       A[i,j]:=MatrixUnit[i,k];
     end do;
   end do;
   Delta:=NumberAcceptedFundamentals - linalg[rank](MatrixUnit);
   if Delta>0 then
      error "There are too many accepted fundamental units: ", eval(MatrixFundamentals), ".  Use Exclude to remove ", Delta, " of them prior to the Initialize statement.";
   fi;
   det:=LinearAlgebra[Determinant](A);
   if det=0 then error "The determinant of the right square A matrix of UnitMatrix is zero.  Shift the order of the physical paramters in Initialize to get a non-zero determinant." fi;
   B:=Matrix(NumberAcceptedFundamentals,
             NumberAcceptedParams-NumberAcceptedFundamentals);
   for i from 1 to NumberAcceptedFundamentals do
     for j from 1 to NumberAcceptedParams-NumberAcceptedFundamentals do
       B[i,j]:=MatrixUnit[i,j]
     end do;
   end do;
   C:=-LinearAlgebra[Transpose](
       LinearAlgebra[MatrixMatrixMultiply](LinearAlgebra[MatrixInverse](A),B));
   Groups:=NumberAcceptedParams-linalg[rank](MatrixUnit)+NumberUnitlessParams;
   GroupsDef:=Matrix(Groups,NumberAcceptedParams+NumberUnitlessParams,0);
   for i from 1 to NumberAcceptedParams do
     GroupsLabel[i]:=MatrixParams[i]
   end do;
   if NumberUnitlessParams>0 then
     for i from 1 to NumberUnitlessParams do
       GroupsLabel[i+NumberAcceptedParams]:=UnitlessParams[i]
     end do;
   fi;
   GroupsLabel:=convert(GroupsLabel,'list');
   if NumberUnitlessParams>0 then
      for i from 1 to NumberUnitlessParams do
        GroupsDef[i,NumberAcceptedParams+i]:=1
      end do;
   fi;
   for i from 1 to (Groups-NumberUnitlessParams) do
     GroupsDef[i+NumberUnitlessParams,i]:=1;
     for j from 1 to (NumberAcceptedParams-Groups+NumberUnitlessParams) do
       GroupsDef[i+NumberUnitlessParams,Groups-NumberUnitlessParams+j]:=
             C[i,j]
     end do;
   end do;
   RETURN(labels=GroupsLabel,PiCoeffs=GroupsDef);
 end proc:
 PrintPiGroups:=proc() description "print the Pi groups in math form";
   local i, j, GroupValues, ParamNames;
   GroupValues:=table();
   ParamNames:=table();
   if Groups=0 then error "no Pi groups are defined" fi;
   for i from 1 to nops(GroupsLabel) do
     ParamNames[i]:=convert(GroupsLabel[i],`name`)
   end do;
   i:='i';
   for i from 1 to Groups do
     j:='j';
     GroupValues[i]:=1;
     for j from 1 to nops(GroupsLabel) do
       GroupValues[i]:=GroupValues[i]*ParamNames[j]^GroupsDef[i,j]
     end do;
   end do;
   RETURN([seq(PI[i]=GroupValues[i],i=1..Groups)]);
 end proc:
end module:
end proc:
module StorePiGroups()
 description "save Pi groups definitions across multiple searches";
 local i, NoGroups, NoParams;
 export PiCoeffs, StoreCoefficients, EnterParameters, PiGroupSummary,
        Initialize, Labels, FindIndependentGroups;
 PiCoeffs:=table();
 Labels:=[];
 NoGroups:=0;
 NoParams:=0;
 Initialize:=proc()
   description "initialize the storage values to null";
   PiCoeffs:=table();
   Labels:=[];
   NoGroups:=0;
   NoParams:=0;
   RETURN("Initialized");
 end proc;
 EnterParameters:=proc(label::`list`)
   description "enter the parameter labels for columns in Pi number storage";
   local i;
   Labels:=label;
   NoParams:=nops(label);
   RETURN(label);
 end proc;
 StoreCoefficients:=proc(label::`list`,coef::`Matrix`)
   description "save Pi coefficients into master list";
   local i, j, k, NoEntries;
   if not nops(label)=NoParams then error "wrong number of entries in first argument" fi;
   NoEntries:=op(1,coef)[1];
   if not NoEntries>0 then error "bad matrix of coefficients" fi;
   for i from 1 to nops(label) do
     member(label[i],Labels,'k');
     for j from 1 to NoEntries do
       PiCoeffs[NoGroups+j,k]:=coef[j,i]
     end do;
   end do;
   NoGroups:=NoGroups+NoEntries;
   RETURN(PiCoeffs);
 end proc;
 PiGroupSummary:=proc()
   description "return the stored information on Pi groups";
   local i, j, GroupMatrix, GroupSet, Item, GroupPrint, ParamNames;
   ParamNames:=table();
   GroupSet:={};
   GroupPrint:=table();
   for i from 1 to NoGroups do
     GroupSet:=GroupSet union {[seq(PiCoeffs[i,j],j=1..NoParams)]}
   end do;
   i:=0; j:='j';
   GroupMatrix:=matrix(nops(GroupSet),NoParams);
   for Item in GroupSet do
     i:=i+1;
     for j from 1 to NoParams do
       GroupMatrix[i,j]:=Item[j]
     end do;
   end do;
   i:='i';
   for i from 1 to nops(Labels) do
     ParamNames[i]:=convert(Labels[i],`name`)
   end do;
   i:='i';
   for i from 1 to nops(GroupSet) do
     j:='j';
     GroupPrint[i]:=1;
     for j from 1 to nops(Labels) do
       GroupPrint[i]:=GroupPrint[i]*ParamNames[j]^GroupMatrix[i,j]
     end do;
   end do;
   i:='i';
   RETURN('ParamNames'=Labels,'GroupsDefs'=eval(GroupMatrix),
          'PiGroups'=[seq(PI[i]=GroupPrint[i],i=1..nops(GroupSet))]);
 end proc;
 FindIndependentGroups:=proc(SelectedGroups::Matrix)
   description "find all groups that are independent in regards to selected groups";
   local i, j, GroupMatrix, GroupSet, Item, GroupPrint, ParamNames,
         IndependentGroups, TestMatrix, IndSet;
   ParamNames:=table();
   GroupSet:={};
   GroupPrint:=table();
   for i from 1 to NoGroups do
     GroupSet:=GroupSet union {[seq(PiCoeffs[i,j],j=1..NoParams)]}
   end do;
   i:=0; j:='j';
   GroupMatrix:=Matrix(nops(GroupSet),NoParams);
   for Item in GroupSet do
     i:=i+1;
     for j from 1 to NoParams do
       GroupMatrix[i,j]:=Item[j]
     end do;
   end do;
   i:='i';
   for i from 1 to nops(Labels) do
     ParamNames[i]:=convert(Labels[i],`name`)
   end do;
   i:='i';
   for i from 1 to nops(GroupSet) do
     j:='j';
     GroupPrint[i]:=1;
     for j from 1 to nops(Labels) do
       GroupPrint[i]:=GroupPrint[i]*ParamNames[j]^GroupMatrix[i,j]
     end do;
   end do;
   # try one row from GroupMatrix at a time for linear independence
   i:='i';j:='j';
   IndSet:={};
   TestMatrix:=Matrix(LinearAlgebra[RowDimension](SelectedGroups)+1,
                      LinearAlgebra[ColumnDimension](SelectedGroups));
   for i from 1 to LinearAlgebra[RowDimension](SelectedGroups) do
     for j from 1 to LinearAlgebra[ColumnDimension](SelectedGroups) do
       TestMatrix[i,j]:=SelectedGroups[i,j]
     end do;
   end do;
   i:='i';
   for i from 1 to nops(GroupSet) do
     j:='j';
     for j from 1 to LinearAlgebra[ColumnDimension](SelectedGroups) do
       TestMatrix[LinearAlgebra[RowDimension](SelectedGroups)+1,j]:=
           GroupMatrix[i,j]
     end do;
     if LinearAlgebra[Rank](TestMatrix)=
        (LinearAlgebra[RowDimension](SelectedGroups)+1)  then
        IndSet:=IndSet union {i} fi;
   end do;
   RETURN(IndSet,'PiGroups'=[seq(PI[IndSet[i]]=
          GroupPrint[IndSet[i]],i=1..nops(IndSet))]);
 end proc:
end module:
 

Application of Pi Theorem 

To use the PiTheorem module, you must first define Maple variables as the physical parameters of a physical system.  Maple knows the dimensions for numerous physical parameters.  Here are its known physical dimensions. 

> GetDimensions();
 

absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
absorbed_dose, acceleration, action, amount_of_information, amount_of_substance, angular_acceleration, angular_jerk, angular_speed, area, currency, dose_equivalent, dynamic_viscosity, electric_capacit...
(3.1)
 

The AddDimension command lets you add new dimensions to the system.  For example, basis weight in paper manufacture is defined as the grams per square meter of surface area.  It is defined to the system in terms of previously defined dimensions as follows using AddDimension: 

> AddDimension(basis_weight=mass/length^2);
 

 

Overview: 

  • Define the physical parameter variables with their unit types.
 

  • Create a module instance for performing the analysis via a call to GeneratePiTheorem.  It creates the module with the desired name such as Case:  GeneratePiTheorem(Case):
 

  • Case:-Exclude is available for very special cases when one or more fundamental units must be dropped from the analysis.  The software will advise when it is necessary to use exclude.
 

  • Initialize Case with its parameters:  Case:-Initialize(........)
 

  • Check for valid data:  Case:-Check()
 

  • Find the Π groups:  Case:-FindPiGroups
 

  • Print the Π groups:  Case:-PrintPiGroups
 

 

Several examples are provided to show its usage. 

Traditional Pendulum Example 

The period of a pendulum is related to the pendulum length, the acceleration of gravity and the release angle.  First, enter the physical parameter variables: 

> t:=time:  # period (time for a complete cycle in movement)
l:=length: # length of the pendulum arm
g:=acceleration:  # acceleration of gravity
theta:=1:  # release angle:  it is unitless for this case
 

Create a PiTheorem module instance called Case1 for this example. 

> GeneratePiTheorem(Case1):
 

Initialize the module instance with the physical parameter data as follows.  Note that parameter t is placed first in the list since it is the main variable of concern.  The method will create Typesetting:-mrow(Typesetting:-mi( groups with t found only in Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(The variable names are entered to the initialization as a 'name'=name.  'name' delays the evaluation so that the actual name gets passed to the routine. 

> Case1:-Initialize(['t'=t,'l'=l,'g'=g,'theta'=theta]);
 

Perform the initial calculations and check for valid solutions, 

> Case1:-Check();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.1.1)
 

Find the Π groups, 

> Case1:-FindPiGroups();
 

labels = [[ (3.1.2)
 

Print the Π groups from the rows of Typesetting:-mrow(Typesetting:-mi(:  

> Case1:-PrintPiGroups();
 

[PI[1] = theta, PI[2] = `/`(`*`(t, `*`(`^`(g, `/`(1, 2)))), `*`(`^`(l, `/`(1, 2))))] (3.1.3)
 

Then, the resulting mathematical relationship for the pendulum is in the form of Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(Therefore, Typesetting:-mrow(Typesetting:-mi(. 

 

What if you attempted to add the mass of the pendulum as a physical parameter to the model?   

> m:=mass;  # new variable m for the pendulum mass
GeneratePiTheorem(Case1a):   # new module instance
Case1a:-Initialize(['t'=t,'l'=l,'g'=g,'theta'=theta,'m'=m]);
Case1a:-Check();
 

 

mass
Fundamental unit ( mass ) has only one entry within the groups.  You must drop the parameter containing it or add another physical parameter with that fundamental unit.
 

Error, (in Check) there is a row with only one entry for the fundamental unit  

The check step now fails.  One of the rules for the Pi Theorem is that each fundamental unit within the proposed physical parameters must occur in at least two physical parameters.  Otherwise, it is not possible to form a dimensionless group with the physical parameter.  If the pendulum mass is actually required to model the physical system, then there must be another physical parameter added that includes mass in its dimensions. 

 

Terminal Raindrop Velocity 

Falling raindrops reach a maximum velocity as they fail to earth.  It is proposed that the terminal velocity is related to the radius of the raindrop, the density of the air, the viscosity of the air and the earth's acceleration of gravity.  The Pi Theorem is applied as follows: 

> v:=speed:  # terminal raindrop velocity
rho:=mass_density:  # air density
r:=length: # radius of raindrop
mu:=dynamic_viscosity:  # air viscosity
g:=acceleration:  # earth's gravity
 

Create a PiTheorem module instance for this example, 

> GeneratePiTheorem(Case2):
 

Initialize the module instance with the physical parameter data as follows.  Note that parameter v is placed first in the list since it is the main variable of concern. 

> Case2:-Initialize(['v'=v,'rho'=rho,'r'=r,'mu'=mu,'g'=g]);
 

Perform the initial calculations and check for valid solutions, 

> Case2:-Check();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.2.1)
 

> Case2:-FindPiGroups();
 

labels = [[ (3.2.2)
 

Print the Π groups, 

> Case2:-PrintPiGroups();
 

[PI[1] = `/`(`*`(v), `*`(`^`(r, `/`(1, 2)), `*`(`^`(g, `/`(1, 2))))), PI[2] = `/`(`*`(rho, `*`(`^`(r, `/`(3, 2)), `*`(`^`(g, `/`(1, 2))))), `*`(mu))] (3.2.3)
 

Note that there are two Typesetting:-mrow(Typesetting:-mi( groups and that the first two physical parameters in the entry list were selected to be in only one of the two Typesetting:-mrow(Typesetting:-mi( groups and to be raised to the first power.  By placing the terminal velocity as the first physical parameter entry, it gets to be only within the first Typesetting:-mrow(Typesetting:-mi( group.  That is a good feature for our model of terminal raindrop velocity to have. 

 

You may change the second physical parameter in the list and get another set of Pi groups: 

> GeneratePiTheorem(Case2a):
 

> Case2a:-Initialize(['v'=v,'r'=r,'rho'=rho,'mu'=mu,'g'=g]);
 

> Case2a:-Check();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.2.4)
 

> Case2a:-FindPiGroups();
 

labels = [[ (3.2.5)
 

The new Π groups are: 

> Case2a:-PrintPiGroups();
 

[PI[1] = `/`(`*`(v, `*`(`^`(rho, `/`(1, 3)))), `*`(`^`(mu, `/`(1, 3)), `*`(`^`(g, `/`(1, 3))))), PI[2] = `/`(`*`(r, `*`(`^`(rho, `/`(2, 3)), `*`(`^`(g, `/`(1, 3))))), `*`(`^`(mu, `/`(2, 3))))] (3.2.6)
 

The analysis does not work for all cases.  If ρ and μ were entered first and second in the Initialize list, then the analysis tries to find a solution where Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( has ρ to the first power without μ present and Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( has μ to the first power without ρ present.  It is not feasible.  The module responds with an error and recommends changing the order of the physical parameters. 

> GeneratePiTheorem(Case2b):
Case2b:-Initialize(['rho'=rho,'mu'=mu,'v'=v,'r'=r,'g'=g]);
Case2b:-Check();
Case2b:-FindPiGroups();
 

 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
Error, (in FindPiGroups) The determinant of the right square A matrix of UnitMatrix is zero.  Shift the order of the physical paramters in Initialize to get a non-zero determinant.
 

Heat Transfer in a Pipe 

The rate of heat transfer of a fluid in a pipe is given by Typesetting:-mrow(Typesetting:-mi(Typesetting:-mrow(Typesetting:-mo( 

Heat Flow = heat transfer coefficient * area * temperature difference between the fluid and the pipe wall 

The heat transfer coefficient is related to six other parameters.  The parameter list is: 

> h:=heat_transfer_coefficient:  # heat transfer coefficient
rho:=mass_density:  # density of the fluid in the pipe
Cp:=specific_heat_capacity:  # fluid heat capacity
k:=thermal_conductivity: # fluid thermal conductivity
mu:=dynamic_viscosity:  # fluid viscosity
v:=speed:  # fluid velocity
Dia:=length:  # pipe inside diamter
 

> GeneratePiTheorem(Case3):   # new module instance
Case3:-Initialize(['h'=h,'rho'=rho,'Cp'=Cp,'k'=k,'mu'=mu,'v'=v,'Dia'=Dia]);
Case3:-Check();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.3.1)
 

> Case3:-FindPiGroups();
 

labels = [[ (3.3.2)
 

The resulting Π groups are: 

> Case3:-PrintPiGroups();
 

[PI[1] = `/`(`*`(h, `*`(Dia)), `*`(k)), PI[2] = `/`(`*`(rho, `*`(v, `*`(Dia))), `*`(mu)), PI[3] = `/`(`*`(Cp, `*`(mu)), `*`(k))] (3.3.3)
 

The groups are known as the Nusselt number, Reynolds number and Prandtl number. 

Find All Pi Groups Feasible  for Heat Transfer in a Pipe 

The seven physical parameters for heat transfer in a pipe are: 

> h:=heat_transfer_coefficient:  # heat transfer coefficient
rho:=mass_density:  # density of the fluid in the pipe
Cp:=specific_heat_capacity:  # fluid heat capacity
k:=thermal_conductivity: # fluid thermal conductivity
mu:=dynamic_viscosity:  # fluid viscosity
v:=speed:  # fluid velocity
Dia:=length:  # pipe inside diamter
 

The heat transfer coefficient is kept as the first parameter and the other six parameters are tested in all permutations in order to find all of the feasible groups from the solution technique. 

> i:=0:
# enter the other parameters (not the prime parameter h) in the following special form
Params:=['''rho'=rho'','''Cp'=Cp'','''k'=k'',
        '''mu'=mu'','''v'=v'','''Dia'=Dia'']:
StorePiGroups:-Initialize():   # use it to store all of the returned Pi groups
# enter the prime parameter h as follows:
StorePiGroups:-EnterParameters(["h",seq(convert(rhs(Params[j]),
                              `string`),j=1..nops(Params))]):
for Item in combinat[choose](Params,3) do
 Params2:=[]:
 for j from 1 to nops(Params) do
   if not member(eval(Params[j]),Item) then Params2:=[op(Params2),j]  fi
 end do;
 j:='j';
 for j from 1 to nops(Params) do
   if member(eval(Params[j]),Item) then Params2:=[op(Params2),j] fi
 end do;
 Params3:=[''h'=h',seq(eval(Params[Params2[k]],1),k=1..nops(Params2))]:
 i:=i+1:
 try
   GeneratePiTheorem(Case2_||i):   # new module instance
   Case2_||i:-Initialize(Params3):
   Case2_||i:-Check():
   val:=Case2_||i:-FindPiGroups():
   StorePiGroups:-StoreCoefficients(rhs(val[1]),rhs(val[2])):
   catch:
 end try;
end do:
 

>
 

> GroupData:=StorePiGroups:-PiGroupSummary();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.4.1)
 

Typesetting:-mrow(Typesetting:-mi(,  Typesetting:-mrow(Typesetting:-mi( and Typesetting:-mrow(Typesetting:-mi( correspond to the groups found in the previous section.  There are six more Π groups that are feasible.  The Π theorem requires that the three selected Π groups are independent. 

Suppose that  you select the Typesetting:-mrow(Typesetting:-mi( and Typesetting:-mrow(Typesetting:-mi( groups.  Which of the remaining seven Pi groups are independent of these two Pi groups.  The module provides a routine to find them. 

> GroupDefs:=convert(rhs(GroupData[2]),Matrix):
# enter the two selected group numbers
# **** Review the results from (3.4.1) to find the two desired groups.
# **** The numbers change between different executions of the commands.
SelectedGroups:=[1,5]:
i:='i': DeleteList:=[]:
for i from 1 to LinearAlgebra[RowDimension](GroupDefs) do
 if not member(i,SelectedGroups) then
    DeleteList:=[i,op(DeleteList)] fi
end do;
GroupDefs:=LinearAlgebra[DeleteRow](GroupDefs,DeleteList):
IndGroups:=StorePiGroups:-FindIndependentGroups(GroupDefs);
 

{2, 3, 6, 7, 8, 9}, PiGroups = [PI[2] = `/`(`*`(h), `*`(rho, `*`(Cp, `*`(v)))), PI[3] = `/`(`*`(k), `*`(rho, `*`(Cp, `*`(v, `*`(Dia))))), PI[6] = `/`(`*`(Cp, `*`(mu)), `*`(k)), PI[7] = `/`(`*`(rho, `*...
{2, 3, 6, 7, 8, 9}, PiGroups = [PI[2] = `/`(`*`(h), `*`(rho, `*`(Cp, `*`(v)))), PI[3] = `/`(`*`(k), `*`(rho, `*`(Cp, `*`(v, `*`(Dia))))), PI[6] = `/`(`*`(Cp, `*`(mu)), `*`(k)), PI[7] = `/`(`*`(rho, `*...
(3.4.2)
 

6 groups are independent from the two selected groups.   

 

Now try again with a selection of Pi groups Typesetting:-mrow(Typesetting:-mi( and Typesetting:-mrow(Typesetting:-mi(. 

> GroupDefs:=convert(rhs(GroupData[2]),Matrix):
# enter the two selected group numbers
# **** Review the results from (3.4.1) to find the two desired groups.
# **** The numbers change between different executions of the commands.
SelectedGroups:=[1,6]:
i:='i': DeleteList:=[]:
for i from 1 to LinearAlgebra[RowDimension](GroupDefs) do
 if not member(i,SelectedGroups) then
    DeleteList:=[i,op(DeleteList)] fi
end do;
GroupDefs:=LinearAlgebra[DeleteRow](GroupDefs,DeleteList):
IndGroups:=StorePiGroups:-FindIndependentGroups(GroupDefs);
 

{2, 5, 8}, PiGroups = [PI[2] = `/`(`*`(h), `*`(rho, `*`(Cp, `*`(v)))), PI[5] = `/`(`*`(h, `*`(Dia)), `*`(k)), PI[8] = `/`(`*`(h, `*`(Dia)), `*`(Cp, `*`(mu)))] (3.4.3)
 

The three Typesetting:-mrow(Typesetting:-mi( groups that contain the heat transfer coefficient are then feasible as independent groups to match with Typesetting:-mrow(Typesetting:-mi( and Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(as the final Typesetting:-mrow(Typesetting:-mi(group. 

>
 

Coffee Warmer 

Reference:  Dr. Thomas Szirtes, "Applied Dimensional Analysis and Modeling," McGraw-Hill, (1998), ISBN 0-07-062811-4, pp. 356-358. 

A cup of coffee is being heated on a hot plate as follows: 

  • heat, Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(is added from the hot plate to the coffee through the bottom flat surface of the mug
 

  • heat, Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(is lost from the coffee to the side wall of the mug
 

  • the mug has a lid that is assumed to perfectly insulate the top of the mug
 

  • the heat transfer from the mug wall is influenced by the heat transfer coefficient, the area and the temperature difference between the coffee and room air
 

The physical system is proposed to be given by five quantities: 

> Delta_t:=thermodynamic_temperature:  # delta temp between coffee and air
h:=heat_transfer_coefficient:  # heat transfer coef from cup to air
AddDimension(heat_flux=energy/time):
Q:=heat_flux: # heat flux to coffee from hot plate
b:=length:  # height of coffee in mug
Dia:=length:  # diameter of mug
 

> GeneratePiTheorem(Case4):   # new module instance
#Case4:-Exclude([time]):
Case4:-Initialize(['Delta_t'=Delta_t,'b'=b,'Q'=Q,'h'=h,'Dia'=Dia]);
Case4:-Check();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.5.1)
 

> Case4:-FindPiGroups();
 

Error, (in FindPiGroups) There are too many accepted fundamental units: , [length, mass, thermodynamic_temperature, time], .  Use Exclude to remove , 1,  of them prior to the Initialize statement.
 

> # Repeating the calculations excluding time dimension from the analysis,
GeneratePiTheorem(Case4):   # new module instance
Case4:-Exclude([time]):
Case4:-Initialize(['Delta_t'=Delta_t,'b'=b,'Q'=Q,'h'=h,'Dia'=Dia]);
Case4:-Check();
 

Typesetting:-mrow(Typesetting:-mverbatim(
Typesetting:-mrow(Typesetting:-mverbatim(
(3.5.2)
 

> Case4:-FindPiGroups();
 

labels = [[ (3.5.3)
 

> Case4:-PrintPiGroups();
 

[PI[1] = `/`(`*`(Delta_t, `*`(h, `*`(`^`(Dia, 2)))), `*`(Q)), PI[2] = `/`(`*`(b), `*`(Dia))] (3.5.4)
 

>
 

 

Legal Notice: The copyright for this application is owned by the author. Neither Maplesoft nor the author are responsible for any errors contained within and are not liable for any damages resulting from the use of this material. This application is intended for non-commercial, non-profit use only. Contact the author for permission if you wish to use this application in for-profit activities. 

Image