MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
Rheology.py
1 
31 
32 
41 
42 from os import getcwd, makedirs, remove, system, symlink, walk
43 from os.path import abspath, dirname, isfile, join, relpath
44 from shutil import copy2
45 from glob import glob
46 import re
47 import json
48 from numpy.linalg import pinv
49 from numpy import sin, cos, pi, matrix, array, dot
50 
51 import modena
52 import SurfaceTension
53 import polymerViscosity
54 from modena import ForwardMappingModel, BackwardMappingModel, SurrogateModel, CFunction, ModenaFireTask
55 import modena.Strategy as Strategy
56 
57 from fireworks.utilities.fw_utilities import explicit_serialize
58 from jinja2 import Template
59 import json
60 
61 from math import pi,sqrt
62 import numpy as np
63 
64 # ----------------------- Convenience variables ----------------------------- #
65 MODULE_DIR = dirname(abspath(__file__))
66 EXECUTION_DIR = getcwd()
67 
68 with open(getcwd()+'/inputs/unifiedInput.json') as jsonfile:
69  inputs=json.load(jsonfile)
70  X_gel=inputs['kinetics']['gelPoint']
71 
72 # ------------------------- Utility functions ------------------------------- #
73 
78 def link_files(src, dst):
79  for dirpath,_,filenames in walk(src):
80  dstpth = join(dst, dirpath[len(src)+1:])
81  relpth = relpath(dirpath, dstpth)
82 
83  #print "In ", dirpath
84  #print "dstPth = ", dstpth
85  #print "relpath = ", relpth
86  #print filenames
87 
88  try:
89  makedirs(dstpth)
90  except:
91  pass
92 
93  lines = []
94  try:
95  with open(join(dirpath,".filesToCopy")) as FILE:
96  lines = FILE.read().splitlines()
97  except:
98  pass
99 
100  for fn in filenames:
101  if any(fnmatch.fnmatch(fn, gl) for gl in lines):
102  dstfn = join(dstpth, fn)
103  srcfn = join(dirpath, fn)
104  if not isfile(dstfn):
105  #print "copying", fn
106  copy2(srcfn, dstfn)
107  else:
108  dstfn = join(dstpth, fn)
109  srcfn = join(relpth, fn)
110  if not isfile(dstfn):
111  #print "linking", fn
112  symlink(srcfn, dstfn)
113 
114 
115 # -------------- Surrogate Functions AND Exact Tasks ------------------------ #
116 
117 # ----------------------------------------------------------------- Dummy model
118 @explicit_serialize
119 
123 class RheologyExactTask_dummy(ModenaFireTask):
124  INPUT_FILE = 'RheologyExact.in'
125  OUTPUT_FILE = 'RheologyExact.out'
126  APPLICATION_CMD = join(MODULE_DIR ,'src/rheologyexactdummy')
127 
128  def task(self, fw_spec):
129 
130  # Write input
131  Template('''{{ s['point']['T'] }}
132  {{ s['point']['shear'] }}
133  {{ s['point']['X'] }}
134  {{ s['point']['m0'] }}
135  {{ s['point']['m1'] }}
136  {{ s['point']['mu'] }}
137  {{ s['point']['ST'] * 0,001 }}'''.strip()).stream(s=self).dump(self.INPUT_FILE)
138 
139 
140  # Execute the detailed model
141  ret = system(self.APPLICATION_CMD)
142  # This enables backward mapping capabilities (not needed in this example)
143  self.handleReturnCode(ret)
144 
145  # Analyse output
146  with open(self.OUTPUT_FILE,'r') as FILE: self['point']['mu_car'] = float(FILE.readline())
147 
148  remove(self.INPUT_FILE)
149  remove(self.OUTPUT_FILE)
150 
151 # Surrogate Function
152 #
153 f_dummy = CFunction(
154  Ccode= '''
155 #include "modena.h"
156 #include "math.h"
157 #include <stdio.h>
158 
159 void rheology_dummy_SM
160 (
161  const modena_model_t* model,
162  const double* inputs,
163  double *outputs
164 )
165 {
166  {% block variables %}{% endblock %}
167 
168  const double lambda = parameters[0];
169  const double alpha = parameters[1];
170  const double n_rh = parameters[2];
171 
172  const double A_mu = 0.0387; // could be loaded from some library for consistence
173  const double E_mu = 10000;
174  const double R_rh = 8.314;
175  const double mu_a = 1.5;
176  const double mu_b = 1;
177  const double mu_c = 0;
178  const double mu_d = 0.001;
179  const double X_gel = '''+str(X_gel)+''';
180  const double mu_0_const = 0.195;
181  const double mu_inf_const = 0.266;
182 
183  double mu_0, mu_inf;
184  double mu_car;
185 
186  if (X<X_gel) {
187  mu_0 = (log(X+mu_d) - log(mu_d) + pow(X_gel / ( X_gel - X ), mu_a + X*mu_b + mu_c*pow(X,2))) * mu_0_const;
188  mu_inf = (log(X+mu_d) - log(mu_d) + pow(X_gel / ( X_gel - X ), mu_a + X*mu_b + mu_c*pow(X,2)))* mu_inf_const;
189 
190  mu_car = (mu_inf + (mu_0 - mu_inf)*pow(1 + pow(lambda*shear,alpha), (n_rh - 1) / alpha));
191  } else {
192  mu_car = 1e6;
193  }
194  // printf("apparent viscosity car %f", mu_car);
195  outputs[0] = mu_car;
196 }
197 ''',
198  # These are global bounds for the function
199  inputs={
200  'T': {'min': 0, 'max': 550 },
201  'shear': {'min': 0, 'max': 9e99 },
202  'X': {'min': 0, 'max': 1 },
203  'm0': {'min': 0, 'max': 9e99 },
204  'm1': {'min': 0, 'max': 9e99 },
205  'mu': {'min': 0, 'max': 1000 },
206  'ST': {'min': 0, 'max': 100 },
207  },
208  outputs={
209  'mu_car': { 'min': 0, 'max': 9e99, 'argPos': 0 },
210  },
211  parameters={
212  'lamdba': { 'min': 1.35, 'max': 21.35, 'argPos': 0 },
213  'alpha': { 'min': 0, 'max': 2, 'argPos': 1 },
214  'n_rh': { 'min': 0, 'max': 2, 'argPos': 2 },
215  },
216 )
217 
218 # ------------------------------------------------------------------ tFEM model
219 @explicit_serialize
220 
224 class RheologyExactTask_tFEM(ModenaFireTask):
225  inputTemplate = Template('''{{ s['point']['T'] }}
226  {{ s['point']['shear'] }}
227  {{ s['point']['X'] }}
228  {{ s['point']['mu'] }}
229  {{ s['point']['ST'] * 0.001 }}
230  {{ s['point']['m0'] }}
231  {{ s['point']['m1'] }}'''.strip())
232 
233 
236  def post_processing(self, fname="RheologyExact.out"):
237  fname = glob("bulk_stress_*.out")
238  print "Reading output file: %s" %(fname)
239  # 1) Read and process raw data
240  fc = tuple(open(fname[0], 'r'))# Read file
241  DATA = [[float(n) for n in re.findall(r'-?\d+.?\d+',l)] for l in fc]
242  del fc# Delete raw file content
243 
244  # 2) First line of file contains parameters for the simulation
245  header = ('strain', 'omega', 'dt', 'eta_p', 'Gamma', 'r')
246  params = { k: v for (k, v) in zip(header, DATA.pop(0)) }
247  # DATA structure: [[t, Gxx, Gxy, Gyy, dt, eta, dot_gamma, gamma]_1,...]
248 
249  # 3) Remove effects due to the initial conditions
250  Tc = 2*pi/params['omega']/params['dt']
251  tc = int(1*Tc)
252  te = int(6*Tc)
253 
254  K = (te-tc)/1
255  DATA = zip(*DATA[tc:te])
256 
257  # DATA = [ col for col in zip(*DATA) ]# Remove entries
258  # DATA structure now transposed: [[t_0 ... t_n], [Gxx_1 ... Gxx_n],...]
259 
260  # 4) Generate input and response matrices
261  Y = np.matrix( DATA[2] ).transpose()# Response matrix
262 
263  si = params['strain']*np.sin(params['omega']*np.array(DATA[0]) )# Sine terms
264  co = params['strain']*np.cos(params['omega']*np.array(DATA[0]) )# Cosine term
265  X = np.matrix( zip(*[si, co]) )# Input matrix
266 
267  del si, co, DATA
268 
269  # 5) Perform linear regression
270  b = np.linalg.pinv(X)*Y# pinv: Moore-Penrose pseudo-inverse
271 
272  # 6) eta_posity = abs(b0 + b1) / omega
273  bsum = np.dot( b.T, b ).A1[0]# Inner product sums "b" vector
274  eta = sqrt( bsum )/params['omega']#
275 
276  return eta
277 
278 
282  link_files(join(MODULE_DIR,"src"), getcwd())
283  return system(MODULE_DIR+'/src/rheology')
284 
285 
287  def task(self, fw_spec):
288 
289  fin="RheologyExact.in"
290 
291  # This enables backward mapping capabilities (not needed in this example)
292  self.inputTemplate.stream(s=self).dump(fin)
293 
294  # call execution
295  self.handleReturnCode( self.execute_simulation() )
296 
297  # call post processing
298  self['point']['mu_car'] = self.post_processing()
299 
300 
301 
302 f_tFEM = CFunction(
303  Ccode= '''
304 #include "modena.h"
305 #include "math.h"
306 #include <stdio.h>
307 
308 void rheology_tFEM_SM
309 (
310  const modena_model_t* model,
311  const double* inputs,
312  double *outputs
313 )
314 {
315  {% block variables %}{% endblock %}
316 
317  const double lambda = parameters[0];
318  const double alpha = parameters[1];
319  const double n_rh = parameters[2];
320 
321  const double A_mu = 0.0387; // could be loaded from some library for consistence
322  const double E_mu = 10000;
323  const double R_rh = 8.314;
324  const double mu_a = 1.5;
325  const double mu_b = 1;
326  const double mu_c = 0;
327  const double mu_d = 0.001;
328  const double X_gel = 0.615;
329  const double mu_0_const = 0.195;
330  const double mu_inf_const = 0.266;
331 // const double lambda = 11.35 ;
332 // const double alpha = 2;
333 // const double n_rh = 0.2;
334 
335  double mu_0, mu_inf, f_t;
336  double mu_car;
337 
338  mu_0 = (log(X+mu_d) - log(mu_d) + pow(X_gel / ( X_gel - X ), mu_a + X*mu_b + mu_c*pow(X,2))) * mu_0_const;
339  mu_inf = (log(X+mu_d) - log(mu_d) + pow(X_gel / ( X_gel - X ), mu_a + X*mu_b + mu_c*pow(X,2)))* mu_inf_const;
340  f_t = A_mu * exp(E_mu / R_rh / T );
341 
342  mu_car = (mu_inf + (mu_0 - mu_inf)*pow(1 + pow(lambda*shear,alpha), (n_rh - 1) / alpha)) * f_t;
343  //printf("apparent viscosity %f", mu_ap);
344  outputs[0] = mu_car;
345 }
346 ''',
347  # These are global bounds for the function
348  inputs={
349  'T': {'min': 0, 'max': 550 },
350  'shear': {'min': 0, 'max': 9e99 },
351  'X': {'min': 0, 'max': 1 },
352  'm0' : {'min': 0, 'max' : 9e99},
353  'm1' : {'min': 0, 'max' : 9e99},
354  'mu': {'min': 0, 'max': 1000 },
355  'ST': {'min': 0, 'max': 100 },
356  },
357  outputs={
358  'mu_car': { 'min': 0, 'max': 9e99, 'argPos': 0 },
359  },
360  parameters={
361  'lamdba': { 'min': 1.35, 'max': 21.35, 'argPos': 0 },
362  'alpha': { 'min': 0, 'max': 2, 'argPos': 1 },
363  'n_rh': { 'min': 0, 'max': 2, 'argPos': 2 },
364  },
365 )
366 
367 # --------------------------------------------------------------------------- #
368 
369 m = BackwardMappingModel(
370  _id= 'Rheology',
371  surrogateFunction= f_dummy,
372  exactTask= RheologyExactTask_dummy(),
373 # surrogateFunction= f_tFEM,
374 # exactTask= RheologyExactTask_tFEM(),
375  substituteModels= [ polymerViscosity.m_polymerViscosity, SurfaceTension.m],
376  initialisationStrategy= Strategy.InitialPoints(
377  initialPoints=
378  {
379  'T': [270.0, 330.0],
380  'shear': [0, 10000],
381  'X': [0, 0.3],
382  'm0': [ 2.5e10, 1.1e10],
383  'm1': [ 0.1, 0.1],
384  },
385  ),
386  outOfBoundsStrategy= Strategy.ExtendSpaceStochasticSampling(
387  nNewPoints= 4
388  ),
389  parameterFittingStrategy= Strategy.NonLinFitWithErrorContol(
390  testDataPercentage= 0.2,
391  maxError= 0.5,
392  improveErrorStrategy= Strategy.StochasticSampling(
393  nNewPoints= 2
394  ),
395  maxIterations= 5 # Currently not used
396  ),
397 )
398 
399 
def execute_simulation(self)
Method executing the detailed model.
Definition: Rheology.py:281
def post_processing(self, fname="RheologyExact.out")
Analyse output.
Definition: Rheology.py:236
def link_files(src, dst)
Function symlinking all files and directories from directory "src" sto the directory "dst"...
Definition: Rheology.py:77
A FireTask that starts a microscopic code and updates the database.
Definition: Rheology.py:122
def task(self, fw_spec)
Method executed by FireWorks.
Definition: Rheology.py:287
A FireTask that starts a microscopic code and updates the database.
Definition: Rheology.py:224