class PCCMatchObjective:
def __init__(self, cpr_model, b, pc_data=None, pc_error=None, pc_weight=None):
self.cpr_model = cpr_model
self.b = b
self.pc_data = pc_data
self.pc_error = pc_error
self.pc_weight = pc_weight
self.counter = 0
def __call__(self, params):
"""This function is called by the optimizer; calculate mismatch vector."""
self.counter += 1
# Build new capillary model from current parameters
cpr_model = self.params_to_cprmodel(params)
# Sw match
swav_data = self.pc_data.swav.values
Pc_data = self.pc_data.Pc.values
swf = np.linspace(cpr_model.swi, cpr_model.swini, 100)
Pc = cpr_model.calc(swf)
swav_sim = cpr_model.calc_av(swf, self.b, Pc)
# Interpolate swav_simulation to measured Pc
swav_sim_inter = np.zeros(len(Pc_data))
g = interp1d(
Pc,
swav_sim,
kind="linear",
bounds_error=False,
fill_value=(swav_sim[-1], swav_sim[0]),
)
for i in range(len(Pc_data)):
swav_sim_inter[i] = g(Pc_data[i])
swav_mismatch = (swav_sim_inter - swav_data) * self.pc_weight / self.pc_error
mismatch = swav_mismatch.flatten()
return mismatch
def params_to_cprmodel(self, params):
v = params.valuesdict()
swini = v["swini"]
swi = v["swi"]
L = v["L"]
E = v["E"]
T = v["T"]
Pc_max = v["Pc_max"]
Pt = v["Pt"]
# We take Sorw for Pc to the right of the relperm Sorw
cpr_model = LET_DR(swini, swi, L, E, T, Pc_max, Pt)
return cpr_model