DFN and Thermal engine

Asked by ahmad mostafa

Hello,

Can we combine between thermal engine and DFNengine, example : If i want to include a fracture in a sample and run temperature inside the whole sample excluding the fracture i inserted (in the fracture i want to run the single phase flow which is already implemented " trickpermeability " ) , Is that possible ?

cheers

Question information

Language:
English Edit question
Status:
Answered
For:
Yade Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Robert Caulk (rcaulk) said :
#1

Hello,

>> Can we combine between thermal engine and DFNengine,

Yes.

>> If i want to include a fracture in a sample and run temperature inside the whole sample excluding the fracture i inserted

What does "run temperature" mean? Why don't you want heat advection in the fracture?

Cheers,

Robert

Revision history for this message
ahmad mostafa (ahmadmo) said (last edit ):
#2

Thank you for responding and Sorry for the unscientific description " run temperature ", I should re-read your paper to remember what have you done .

However currently I am developing Mass transport engine and I am following the steps you followed in the thermal engine. I exactly need a diffusion single phase flow in the matrix which i have already done and validated it and a advection- diffusion multi-phase flow in the cleat system. As a first step I am trying to combine the Mass transport engine with the DFN engine.

You already answered my question , and concerning your second question I need to run as a first step single phase advection flow in fractures with single phase diffusive flow in the matrix then develop it to advection diffusion two phase flow in the fractures.

Can I find a python script that combines the DFN and the thermal engine ?

Cheers,

Revision history for this message
Robert Caulk (rcaulk) said :
#3

>>Can I find a python script that combines the DFN and the thermal engine ?

I do not know of such a script. But as for code it is simply adding the two engines to the engine list. Of course you need to know how to handle DFNFlowEngine and ThermalEngine parameters and geometrical considerations - but it seems you are not using ThermalEngine so that is irrelevant.

Revision history for this message
Robert Caulk (rcaulk) said :
#4

Hello,

I received your email, but it is important that all discussions remain on launchpad for other users to benefit. You are asking me if I am "sure that ThermalEngine works with DFNFlowEngine."

DFNFlowEngine is not compiled by default - so there is some implication here that the user knows how to compile and edit C++ to get it to work. I guess this is already clear since I helped you with the compilation of DFNFlowEngine a couple weeks ago. This means DFNFlow is untested and unmaintained. Yes, tragic. As the rest of Yade continues to evolve and remain maintained, DFNFlowEngine becomes more and more lost behind and will continue to require more and more manual intervention to keep running.

That said, the architecture of ThermalEngine fits together with DFNFlowEngine since DFNFlowEngine is simply another FlowEngine. Of course, there may be some bugs that you need to iron out if you want to go down the path, but none of them are structural issues.

Based on your email you are running into some bug, but you did not provide any indication of where the error arises (line numbers, files), what the error is in the terminal (copy and paste to here), what you have tried, what is your MWE. etc etc.

Thanks for providing the necessary info for me to help you debug your problem,

Robert

Revision history for this message
ahmad mostafa (ahmadmo) said :
#5

Thank you for replying. Here is the error = core dumped.

yade flowScenario.py
Welcome to Yade 2022-02-18.git-d331682
Using python version: 3.6.9 (default, Dec 8 2021, 21:08:43)
[GCC 8.4.0]
TCP python prompt on localhost:9000, auth cookie `cssdyk'
XMLRPC info provider on http://localhost:21000
Running script flowScenario.py
num bodies 216
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
infinite K1!
CHOLMOD Time to build linear equations 52
CHOLMOD sparse: Achol: 1039-by-1039, nz 3069, upper. OK
CHOLMOD Time to allocate matrix 92
Reusing reordering? 0. CHOLMOD Time to Analyze 2454
CHOLMOD warning: matrix not positive definite. file: ../Supernodal/t_cholmod_super_numeric.c line: 911
CHOLMOD Time to factorize 4672
Segmentation fault (core dumped)

Revision history for this message
ahmad mostafa (ahmadmo) said :
#6

from yade import pack, ymport
from yade import timing
import numpy as np
import shutil
pFactor=1 # to scale the permeability of the rock matrix (test on sample without fracture -> permeametre.py)

#### fracture aperture
jointAperture=1e-3

timeStr = time.strftime('%m-%d-%Y')
num_spheres=1000# number of spheres
young=1e9
rad=0.003

mn,mx=Vector3(0,0,0),Vector3(0.05,0.05,0.05) # corners of the initial packing

thermalCond = 2. #W/(mK)
heatCap = 710. #J(kg K)
t0 = 0 #K

# micro properties
r = rad
k = 2.0 # 2*k*r
Cp = 710.
rho = 2600.
D = 2.*r
m = 4./3.*np.pi*r**2/rho
# macro diffusivity

O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=radians(3),density=2600,label='spheres'))
O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls'))
walls=aabbWalls([mn,mx],thickness=0,material='walls')
wallIds=O.bodies.append(walls)

sp = O.bodies.append(ymport.textExt('5cmEdge_1mm.spheres', 'x_y_z_r',color=(0.1,0.1,0.9), material='spheres'))

print('num bodies ', len(O.bodies))

triax=TriaxialStressController(
 maxMultiplier=1.+2e4/young,
 finalMaxMultiplier=1.+2e3/young,
 thickness = 0,
 stressMask = 7,
 internalCompaction=True,
)

ThermalEngine = ThermalEngine(dead=1,label='thermal');

newton=NewtonIntegrator(damping=0.2)
intRadius = 1
flow=DFNFlowEngine(
        isActivated=1
        ## choose solver to use (0: Gauss Seidel, 1: Taucs, 2: Pardiso, 3: CHOLMOD)
        ,useSolver=3 # 3 should be used by default
        ,fluidBulkModulus=2.2e9

        ## DFN related
        ,clampKValues=False
        ,updatePositions=False
        ,meshUpdateInterval=100
        # controls the size scaling between YADE fracture and real one
        ,jointsResidualAperture=jointAperture
        #,apertureFactor=hFactor
)
O.engines=[
 ForceResetter(),
 InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=intRadius),Bo1_Box_Aabb()]),
 InteractionLoop(
  [Ig2_Sphere_Sphere_ScGeom(interactionDetectionFactor=intRadius),Ig2_Box_Sphere_ScGeom()],
  [Ip2_FrictMat_FrictMat_FrictPhys()],
  [Law2_ScGeom_FrictPhys_CundallStrack()],label="iloop"
 ),
 #FlowEngine(dead=1,label="flow",multithread=False),
 flow,
 ThermalEngine,
 GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.8),
 triax,
 newton
]

for b in O.bodies:
 if isinstance(b.shape, Sphere):
  b.dynamic=False # mechanically static

flow.defTolerance=-1 #0.3
flow.permeabilityFactor= 1
flow.viscosity= 0.001
flow.bndCondIsPressure=[1,1,0,0,0,0]
flow.bndCondValue=[10,0,0,0,0,0]
flow.thermalEngine=True
flow.debug=False
flow.fluidRho = 997
flow.fluidCp = 4181.7
flow.getCHOLMODPerfTimings=True
flow.bndCondIsTemperature=[1,1,1,1,1,1]
flow.thermalEngine=True
flow.thermalBndCondValue=[343.15,343.15,343.15,343.15,343.15,343.15]
flow.tZero=t0
flow.pZero=0
flow.maxKdivKmean=1
flow.minKdivmean=0.0001;

thermal.dead=0
thermal.debug=False
thermal.fluidConduction=True
thermal.ignoreFictiousConduction=True
thermal.conduction=True
thermal.thermoMech=False
thermal.solidThermoMech = False
thermal.fluidThermoMech = False
thermal.advection=True
thermal.bndCondIsTemperature=[0,0,0,0,0,0]
thermal.thermalBndCondValue=[0,0,0,0,0,0]
thermal.fluidK = 0.6069 #0.650
thermal.fluidConductionAreaFactor=1.
thermal.particleT0 = t0
thermal.particleDensity=2600.
thermal.particleK = thermalCond
thermal.particleCp = heatCap
thermal.useKernMethod=True
#thermal.useHertzMethod=False
timing.reset()

O.dt=0.1e-7
O.dynDt=False
O.run(1,1)

Here is the script i am running.

Revision history for this message
Robert Caulk (rcaulk) said :
#7

Hello,

If I were you, I would start debugging the c++ by identifying what part of DFNFlowEngine is infact the issue. For example, you would start with removing the "trickPermeability()" and verifying that works. Then work your way into DFNFlow. You could, for example, just remove any reassignment of permeability to identify if that is the issue.

Robert

Revision history for this message
Luc Scholt├Ęs (luc) said :
#8

Just wondering about the dependencies since I am not entirely clear with how everything is related in the code. How is DFNFlowEngine "linked" to FLowEngine exactly?

For instance, should we add

ifdef DFNFLOW

and/or

include "FlowEngine_DFNFlowEngineT.hpp"

somewhere in the thermalEngine files to make it work?

I thought that DFNFlowEnginee inherited from FlowEngine so that there is no need to write such "dependencies" but is that the case or not?

Sorry if this is a silly question but I must admit this is out of my programming comfort zone. Is there some sort of a "documentation" about how all these dependencies work in YADE PFV related extensions?

Luc

Revision history for this message
Janek Kozicki (cosurgi) said :
#9

I agree that these Flow dependencies are unclear. For example: https://gitlab.com/yade-dev/trunk/-/merge_requests/816#note_825186904

I hope that the authors will clarify things here :)

Revision history for this message
Janek Kozicki (cosurgi) said :
#10
Revision history for this message
Robert Caulk (rcaulk) said :
#11

Hey Luc,

>>How is DFNFlowEngine "linked" to FLowEngine exactly?

From an architectural perspective, DFNFlow interacts with Yade the same way as the PeriodicFlow, TwoPhaseFlow, UnsaturatedFlow, PartialSatClay engines. FlowEngine is a "template" which users can essentially build their own stuff on top of. This means you get all the underlying functionality of the original FlowEngine, and the user only needs to add their tweaks. For DFNFlow, that tweak is the "trickPermeability()" function. But theoretically, the user can override any FlowEngine function they want, while still having access to the entire FlowEngine library and solver (e.g. PartialSatClayEngine overrides action() entirely, but still uses the solver library etc.)

So in other words, when someone runs DFNFlowEngine in their python code, the originally written FlowEngine::action() is running, and all FlowEngine functionality is being executed, but when it arrives to trickPermeability(), it is just using the DFNFlow defined trickPermeability() instead of the original empty one.

ThermalEngine is *not* a template of FlowEngine. This is why all the example scripts include both the FlowEngine and the ThermalEngine. But ThermalEngine does interact quite a lot with FlowEngine (for heat advection). That link is created here [1]. Judging by that line, you may need to at least type "DFNFlowEngine" to make sure it is grabbing the correct object. Here, I try to generalize it so that any named derived FlowEngine will link [2]. Please test it at let me know if it works for your purposes. Thank you.

[1]https://gitlab.com/yade-dev/trunk/-/blob/master/pkg/pfv/Thermal.cpp#L45
[2]https://gitlab.com/yade-dev/trunk/-/merge_requests/844

Revision history for this message
ahmad mostafa (ahmadmo) said :
#12

Hey Robert,

Unfortunately this generalization didn't work, still the thermal engine is interacting with Flow engine but not interacting with DFNEngine.

A few notification that may help :

 1 - What did I notice that if we give a temperature value for pore or solve the temperature field (if possible) from the flowengine or flowboundingsphere, we have no problem but whenever we go to the thermal.cpp and loop over the cells the core is dumped as if there is no mesh between the particles to be read or to loop over (not interacted with DFNEngine).

2 - Concerning the solid phase, there is no problem to combine the thermal engine and DFNEngine if we want to solve the solid-solid conduction only, the problem starts when ever we want to define a mesh to loop over the cells. Exactly from this point " Tesselation& Tes = flow->solver->T[flow->solver->currentTes]; ".

Ahmad

Can you help with this problem?

Provide an answer of your own, or ask ahmad mostafa for more information if necessary.

To post a message you must log in.