44import copy
55
66import sympy as sp
7+ from pyapprox .util .backends .template import BackendMixin , Array
78from pyapprox .util .backends .numpy import NumpyMixin
89from pyapprox .util .sympy import (
910 _evaluate_sp_lambda ,
@@ -19,7 +20,7 @@ class ManufacturedSolution(ABC):
1920 def __init__ (
2021 self ,
2122 nvars : int ,
22- bkd = NumpyMixin ,
23+ bkd : BackendMixin = NumpyMixin ,
2324 oned : bool = False ,
2425 ):
2526 self ._bkd = bkd
@@ -53,14 +54,14 @@ def time_symbol(self):
5354 def all_symbols (self ):
5455 return self .cartesian_symbols () + self .time_symbol ()
5556
56- def _steady_expression_to_function (self , expr ):
57+ def _steady_expression_to_function (self , expr : List ):
5758 all_symbs = self .cartesian_symbols ()
5859 expr_lambda = sp .lambdify (all_symbs , expr , "numpy" )
5960 return partial (
6061 _evaluate_sp_lambda , expr_lambda , bkd = self ._bkd , oned = self ._oned
6162 )
6263
63- def _steady_expression_list_to_function (self , exprs ):
64+ def _steady_expression_list_to_function (self , exprs : List ):
6465 all_symbs = self .cartesian_symbols ()
6566 expr_lambda = [sp .lambdify (all_symbs , expr , "numpy" ) for expr in exprs ]
6667 return partial (
@@ -70,7 +71,7 @@ def _steady_expression_list_to_function(self, exprs):
7071 oned = False ,
7172 )
7273
73- def _steady_expression_list_of_lists_to_function (self , exprs ):
74+ def _steady_expression_list_of_lists_to_function (self , exprs : List ):
7475 all_symbs = self .cartesian_symbols ()
7576 expr_lambda = [
7677 [sp .lambdify (all_symbs , expr , "numpy" ) for expr in row ]
@@ -93,7 +94,7 @@ def _transient_expression_to_function(self, expr):
9394 oned = self ._oned ,
9495 )
9596
96- def _transient_expression_list_to_function (self , exprs ):
97+ def _transient_expression_list_to_function (self , exprs : List ):
9798 all_symbs = self .all_symbols ()
9899 expr_lambda = [sp .lambdify (all_symbs , expr , "numpy" ) for expr in exprs ]
99100 return partial (
@@ -103,7 +104,7 @@ def _transient_expression_list_to_function(self, exprs):
103104 oned = False ,
104105 )
105106
106- def _transient_expression_list_of_lists_to_function (self , exprs ):
107+ def _transient_expression_list_of_lists_to_function (self , exprs : List ):
107108 all_symbs = self .all_symbols ()
108109 expr_lambda = [
109110 [sp .lambdify (all_symbs , expr , "numpy" ) for expr in row ]
@@ -116,7 +117,7 @@ def _transient_expression_list_of_lists_to_function(self, exprs):
116117 oned = False ,
117118 )
118119
119- def is_transient (self ):
120+ def is_transient (self ) -> bool :
120121 return self ._bkd .any (self ._bkd .array (list (self .transient .values ())))
121122
122123 def _expressions_to_functions (self ):
@@ -160,7 +161,7 @@ def _expressions_to_functions(self):
160161 self ._transient_expression_to_function (expr )
161162 )
162163
163- def nvars (self ):
164+ def nvars (self ) -> int :
164165 return self ._nvars
165166
166167 def _set_expression_from_bool (self , name : str , expr , transient : bool ):
@@ -182,7 +183,7 @@ def _set_expression(self, name: str, expr, expr_str: str):
182183 transient = False
183184 self ._set_expression_from_bool (name , expr , transient )
184185
185- def __repr__ (self ):
186+ def __repr__ (self ) -> str :
186187 fields = f"{ self ._expressions } " .split ("," )
187188 expr_str = ",\n " .join (fields )[1 :- 1 ].replace ("'" , "" )
188189 return "{0}(\n {1}\n )" .format (self .__class__ .__name__ , expr_str )
@@ -256,7 +257,9 @@ def _sympy_reaction_expressions(self, react_str, sol_str):
256257 # react_prime_expr = react_prime_expr.subs(
257258 # sol_symb, self._expressions["solution"]
258259 # )
260+ print (react_str )
259261 react_str = react_str .replace ("u" , "({0})" .format (sol_str ))
262+ print (react_str )
260263 return react_str , sp .sympify (react_str ) # , react_prime_expr
261264
262265 def sympy_reaction_expressions (self ):
@@ -832,3 +835,59 @@ def sympy_expressions(self):
832835 self ._set_expression ("viscosity" , visc_expr , self ._visc_str )
833836 self ._set_expression ("flux" , flux_exprs , self ._sol_str )
834837 self ._expressions ["forcing" ] += forc_expr
838+
839+
840+ class ManufacturedStokes (VectorSolutionMixin , ManufacturedSolution ):
841+ def __init__ (
842+ self ,
843+ sol_strs : List [str ],
844+ nvars : int ,
845+ navier_stokes : bool ,
846+ bkd : BackendMixin = NumpyMixin ,
847+ oned : bool = False ,
848+ ):
849+ self ._navier_stokes = navier_stokes
850+ if len (sol_strs ) != nvars + 1 :
851+ raise ValueError (f"len(sol_strs)!={ nvars + 1 } " )
852+ self ._vel_strs = sol_strs [:nvars ]
853+ self ._pres_str = sol_strs [nvars ]
854+ super ().__init__ (sol_strs , nvars , bkd , oned )
855+
856+ def sympy_expressions (self ):
857+ cartesian_symbs = self .cartesian_symbols ()
858+ exprs = self ._expressions ["solution" ]
859+ vel_exprs = exprs [: self ._nvars ]
860+ pres_expr = exprs [self ._nvars ]
861+ vel_forc_exprs = []
862+ for vel , s1 in zip (vel_exprs , cartesian_symbs ):
863+ vel_forc_exprs .append (
864+ sum ([- vel .diff (s2 , 2 ) for s2 in cartesian_symbs ])
865+ + pres_expr .diff (s1 , 1 )
866+ )
867+ if self ._navier_stokes :
868+ vel_forc_exprs [- 1 ] += sum (
869+ [
870+ u * vel .diff (s2 , 1 )
871+ for u , s2 in zip (vel_exprs , cartesian_symbs )
872+ ]
873+ )
874+ pres_forc_expr = sum (
875+ [vel .diff (s , 1 ) for vel , s in zip (vel_exprs , cartesian_symbs )]
876+ )
877+
878+ vel_grad_exprs = [
879+ [v .diff (s , 1 ) for s in cartesian_symbs ] for v in vel_exprs
880+ ]
881+ pres_grad_expr = [pres_expr .diff (s , 1 ) for s in cartesian_symbs ]
882+ flux_exprs = vel_grad_exprs + [pres_grad_expr ]
883+ self ._set_expression ("flux" , flux_exprs , self ._sol_strs [0 ])
884+
885+ self ._set_expression ("vel_forcing" , vel_forc_exprs , self ._sol_strs [0 ])
886+ self ._set_expression (
887+ "pres_forcing" , pres_forc_expr , self ._sol_strs [- 1 ]
888+ )
889+
890+ forc_exprs = vel_exprs + [pres_forc_expr ]
891+ self ._expressions ["forcing" ] = [
892+ f + g for f , g in zip (self ._expressions ["forcing" ], forc_exprs )
893+ ]
0 commit comments