Hi,
I'm new to SfePy and have a (probably) quite trivial question. I have a porous material and want to store/use the materials' thermal conductivities in a post_process function. This should be fairly easy but I somehow can't get it working.
Say I have two materials called "Fill" and "Pore":
materials = { 'Pore' : 'pore_material_func', 'Fill' : 'fill_material_func', }
Their conductivities are defined in *_material_func. In the post_process function I can access the conductivity of Pore with (analog for Fill):
mu = pb.evaluate('ev_volume_integrate_mat.2.Omega(Pore.val, T)', mode='el_avg', copy_materials=False, verbose=False)
However, this gives me a non-zero value in all of Omega, not just in the Pore cells. Is there an easy way to set the conductivity to 0 outside Pore (then I can just add the Pore and Fill conductivities) or directly get the real conductivities in all of Omega?
Thanks a lot and kind regards, Jochen
Hi Jochen,
On 7/2/19 11:36 AM, jd766@cam.ac.uk wrote:
Hi,
I'm new to SfePy and have a (probably) quite trivial question. I have a porous material and want to store/use the materials' thermal conductivities in a post_process function. This should be fairly easy but I somehow can't get it working.
Say I have two materials called "Fill" and "Pore":
materials = { 'Pore' : 'pore_material_func', 'Fill' : 'fill_material_func', }
Their conductivities are defined in *_material_func. In the post_process function I can access the conductivity of Pore with (analog for Fill):
mu = pb.evaluate('ev_volume_integrate_mat.2.Omega(Pore.val, T)', mode='el_avg', copy_materials=False, verbose=False)
However, this gives me a non-zero value in all of Omega, not just in the Pore cells. Is there an easy way to set the conductivity to 0 outside Pore (then I can just add the Pore and Fill conductivities) or directly get the real conductivities in all of Omega?
It depends on what the pore_material_func does when called for points with coordinates outside the Pore cells - does it return zero?
Another way of specifying parameters that are constant per region can be found in [1] (the second example) - does that help?
r.
[1] http://sfepy.org/doc-devel/users_guide.html#materials
Thanks a lot and kind regards, Jochen
Dear Robert,
Thanks a lot for the hint. I got it working now. The example you pointed out did work for me in the sense that I was able to access both region conductivities in the post_process function. However, I couldn’t get a material function for a temperature dependent conductivity working.
But your comment regarding the coordinates outside the Pore cells pointed me in the right direction. This is how I solved it now (I’m not a programmer and am sure there are more elegant ways to do it):
def return_indices_of_a(a, b): b_set = set(b) return [i for i, v in enumerate(a) if v in b_set]
def material_func(ts, coors, problem, equations=None, mode=None, **kwargs): """ Returns the thermal conductivity of the porous material. """ ev = problem.evaluate if mode == 'qp': Om = problem.domain.regions['Omega'].get_cells() Po = problem.domain.regions['Pore'].get_cells() Fi = problem.domain.regions['Fill'].get_cells()
T_omega = np.array(ev('ev_volume_integrate.2.Omega(T)', mode='qp', verbose=False))
val = np.zeros(T_omega.shape)
idx_pore = return_indices_of_a(Om,Po)
idx_fill = return_indices_of_a(Om,Fi)
val[idx_pore,:,0,0]= (-7.61404 + 0.14152*T_omega[idx_pore,:,0,0] - 1.09156e-4*T_omega[idx_pore,:,0,0]**2 + 4.16029e-8*T_omega[idx_pore,:,0,0]**3)/1000
val[idx_fill,:,0,0]=1
output('conductivity: min:', val.min(), 'max:', val.max())
val.shape = (val.shape[0] * val.shape[1], 1, 1)
return {'val' : val}
materials = { 'Omega' : 'material_func', }
Now I have a temperature dependent conductivity for the pores and can access both, the pore and solid conductivities using: problem. evaluate('ev_integrate_mat.2.Omega(Omega.val, T)', mode='el_avg')
Thanks a lot for the help and kind regards, Jochen
Dear Jochen,
On 7/3/19 11:23 AM, jd766@cam.ac.uk wrote:
Dear Robert,
Thanks a lot for the hint. I got it working now. The example you pointed out did work for me in the sense that I was able to access both region conductivities in the post_process function. However, I couldn’t get a material function for a temperature dependent conductivity working.
If you want, send a minimal working example - we can have a look.
But your comment regarding the coordinates outside the Pore cells pointed me in the right direction. This is how I solved it now (I’m not a programmer and am sure there are more elegant ways to do it):
def return_indices_of_a(a, b): b_set = set(b) return [i for i, v in enumerate(a) if v in b_set]
def material_func(ts, coors, problem, equations=None, mode=None, **kwargs): """ Returns the thermal conductivity of the porous material. """ ev = problem.evaluate if mode == 'qp': Om = problem.domain.regions['Omega'].get_cells() Po = problem.domain.regions['Pore'].get_cells() Fi = problem.domain.regions['Fill'].get_cells()
T_omega = np.array(ev('ev_volume_integrate.2.Omega(T)', mode='qp', verbose=False)) val = np.zeros(T_omega.shape) idx_pore = return_indices_of_a(Om,Po) idx_fill = return_indices_of_a(Om,Fi)
IMO you could just use
idx_pore = np.searchsorted(Om, Po)
or, if Omega is the whole domain
idx_pore = Po
(Not tested!)
val[idx_pore,:,0,0]= (-7.61404 + 0.14152*T_omega[idx_pore,:,0,0] - 1.09156e-4*T_omega[idx_pore,:,0,0]**2 + 4.16029e-8*T_omega[idx_pore,:,0,0]**3)/1000 val[idx_fill,:,0,0]=1 output('conductivity: min:', val.min(), 'max:', val.max()) val.shape = (val.shape[0] * val.shape[1], 1, 1) return {'val' : val}
materials = { 'Omega' : 'material_func', }
Now I have a temperature dependent conductivity for the pores and can access both, the pore and solid conductivities using: problem. evaluate('ev_integrate_mat.2.Omega(Omega.val, T)', mode='el_avg')
Another way would be to split the integral to two: one over 'Pore' region, and other over 'Fill' region.
Best regards, r.
Thanks a lot for the help and kind regards, Jochen
participants (2)
-
jd766@cam.ac.uk
-
Robert Cimrman