TangentVectors[f_, {u_, v_}] := {Simplify[D[f, u]], Simplify[D[f, v]]};

Differential[f_, {u_, v_}] := Simplify[Cross[D[f, u], D[f, v]]] ;


FirstFundamentalForm[f_, {u_, v_}] :=
		Block[{Xu, Xv, gE, gF, gG},
	{Xu , Xv} = TangentVectors[f, {u, v}] ;
		
		gE = Simplify[Xu . Xu] ;
		gF = Simplify[Xu . Xv] ;
		gG = Simplify[Xv . Xv] ;
	 {{ gE, gF}, {gF, gG}} 
		];

FirstFundamentalForm[{Xu_, Xv_}] :=
		Block[{gE, gF, gG},
		
		gE = Simplify[Xu . Xu] ;
		gF = Simplify[Xu . Xv] ;
		gG = Simplify[Xv . Xv] ;
	 {{ gE, gF}, {gF, gG}} 
		];

AreaForm[sf_,{u_,v_}]:=
	PowerExpand[
		Sqrt[Det[FirstFundamentalForm[sf,{u,v}]]]];

SurfaceArea[sf_,{u_,u0_,u1_},{v_,v0_,v1_}]:=
    Block[{frm=AreaForm[sf,{u,v}]},
      Simplify[Integrate[frm,{u,u0,u1},{v,v0,v1}]]];
      
NormalVector[{Xu_, Xv_}] :=
		Module[{t},
		t = Simplify[Cross[Xu, Xv]] ;
		Simplify[t /Sqrt[t.t] ]
		];

SecondFundamentalForm[ff_, {u_, v_}] :=
    Block[{Xu , Xv, nrm, Nu, Nv , e, f, g},
		{Xu , Xv} = TangentVectors[ff, {u, v}] ;
		nrm = NormalVector[{Xu , Xv}];
		Nu = Simplify[D[nrm, u]] ;
		Nv = Simplify[D[nrm, v]] ;
		e = - Simplify[Xu . Nu] ;
		f = - Simplify[Xu . Nv] ;
		g = - Simplify[Xv . Nv] ;
	{{e, f}, {f, g}} 
		];

SecondFundamentalForm[{Xu_, Xv_}, nrm_, {u_, v_}] :=	
    Block[{Nu, Nv , e, f, g},
		Nu = Simplify[D[nrm, u]] ;
		Nv = Simplify[D[nrm, v]] ;
		e = - Simplify[Xu . Nu] ;
		f = - Simplify[Xu . Nv] ;
		g = - Simplify[Xv . Nv] ;
	{{e, f}, {f, g}} 
		];

MeanCurvature[f_, {u_, v_}] :=
    Block[
      {Xu , Xv, nrm},
      {Xu , Xv} = TangentVectors[f, {u, v}]; nrm = NormalVector[{Xu , Xv}]; 
      Simplify[Tr[
          Inverse[
              FirstFundamentalForm[{Xu , Xv}]].SecondFundamentalForm[{Xu , 
                Xv}, nrm, {u, v}
              ]
          ]
        ]
      ];

GaussianCurvature[f_, {u_, v_}] :=
    Block[
      {Xu , Xv, nrm},
      {Xu , Xv} = TangentVectors[f, {u, v}] ; nrm = NormalVector[{Xu , Xv}]; 
      Simplify[Det[
            SecondFundamentalForm[{Xu , Xv}, nrm, {u, v}]]/Det[
            FirstFundamentalForm[{Xu , Xv}]
            ]
        ]
      ];

WeingartenMap[f_, {u_, v_}] :=
    Block[
      {Xu , Xv, nrm},
      {Xu , Xv} = TangentVectors[f, {u, v}] ;
      nrm = NormalVector[{Xu , Xv}];
      Simplify[
        Inverse[
            FirstFundamentalForm[{Xu , Xv}]].SecondFundamentalForm[{Xu , Xv}, 
            nrm, {u, v}]
        ]
      ];
		
IsothermalQ[ff_]:=
    ff[[1,1]]==ff[[2,2]]&&ff[[1,2]]==0;
