From 8e5dca6674b9c04e5b8c8614e5dc0add6505bd9d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 8 Jan 2021 10:03:52 -0500 Subject: [PATCH 001/175] Convert binary phase field example to use steppyngstounes --- examples/phase/binary.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index f3938969a2..d51174f162 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -572,19 +572,34 @@ def deltaChemPot(phase, C, T): >>> dt = 1.e-5 >>> if __name__ == '__main__': -... timesteps = 100 +... timesteps = 1000000 ... else: ... timesteps = 10 ->>> from builtins import range ->>> for i in range(timesteps): -... phase.updateOld() -... C.updateOld() -... phaseRes = 1e+10 -... diffRes = 1e+10 -... while phaseRes > 1e-3 or diffRes > 1e-3: -... phaseRes = phaseEq.sweep(var=phase, dt=dt) -... diffRes = diffusionEq.sweep(var=C, dt=dt, solver=solver) +>>> phaseScale = 1e-3 +>>> diffScale = 1e-3 + +>>> phase.updateOld() +>>> C.updateOld() + +>>> from steppyngstounes import PIDStepper, ScaledStepper, FixedStepper, PseudoRKQSStepper +>>> for outer in FixedStepper(start=0., stop=timesteps*dt, tryStep=dt * 100): +... for inner in PseudoRKQSStepper(start=outer.begin, stop=outer.end, tryStep=dt): +... # print("step", inner.begin, inner.size) +... for sweep in range(5): +... phaseRes = phaseEq.sweep(var=phase, dt=inner.size) / phaseScale +... diffRes = diffusionEq.sweep(var=C, dt=inner.size, solver=solver) / diffScale +... # print(" ", sweep, phaseRes, diffRes) +... res = max(phaseRes, diffRes) +... if inner.succeeded(error=res, value=None): +... phase.updateOld() +... C.updateOld() +... print(inner.size) +... else: +... phase.value = phase.old +... C.value = C.old +... dt = inner.want +... outer.succeeded(value=None, error=1.) ... if __name__ == '__main__': ... viewer.plot() From 6e94f8552475253f134f59150aa2d98a0669e4f6 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 9 Jan 2021 21:02:46 -0500 Subject: [PATCH 002/175] Convert to quadratic time stepper for very long times --- examples/phase/binary.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index d51174f162..76d4992207 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -572,9 +572,9 @@ def deltaChemPot(phase, C, T): >>> dt = 1.e-5 >>> if __name__ == '__main__': -... timesteps = 1000000 +... totaltime = 1e10 ... else: -... timesteps = 10 +... totaltime = 1e-4 >>> phaseScale = 1e-3 >>> diffScale = 1e-3 @@ -583,25 +583,43 @@ def deltaChemPot(phase, C, T): >>> C.updateOld() >>> from steppyngstounes import PIDStepper, ScaledStepper, FixedStepper, PseudoRKQSStepper ->>> for outer in FixedStepper(start=0., stop=timesteps*dt, tryStep=dt * 100): -... for inner in PseudoRKQSStepper(start=outer.begin, stop=outer.end, tryStep=dt): + +>>> class SquareStepper(FixedStepper): +... def _adaptStep(self): +... dt = (self.current - self.start) +... if dt == 0: +... dt = super(FixedStepper, self)._adaptStep() +... return dt + +>>> solve = 0 + +>>> t = viewer.axes.text(0.00025, 0.2, "t = 0") + +>>> for outer in SquareStepper(start=0., stop=totaltime, size=dt): +... #print(outer.size) +... for inner in PIDStepper(start=outer.begin, stop=outer.end, size=dt): #, maxStep=2.5): ... # print("step", inner.begin, inner.size) ... for sweep in range(5): ... phaseRes = phaseEq.sweep(var=phase, dt=inner.size) / phaseScale ... diffRes = diffusionEq.sweep(var=C, dt=inner.size, solver=solver) / diffScale ... # print(" ", sweep, phaseRes, diffRes) +... solve += 1 ... res = max(phaseRes, diffRes) ... if inner.succeeded(error=res, value=None): ... phase.updateOld() ... C.updateOld() -... print(inner.size) +... #print("", inner.size) ... else: +... #print("", inner.size, "FAILED", phaseRes, diffRes) ... phase.value = phase.old ... C.value = C.old ... dt = inner.want ... outer.succeeded(value=None, error=1.) ... if __name__ == '__main__': -... viewer.plot() +... t.set_text("t = {:f}".format(outer.end)) +... viewer.plot(filename="binary-{}.png".format(outer.end)) + +>>> print(solve, "total solves") >>> from fipy import input >>> if __name__ == '__main__': From ba57a517b7a7db3d47e49fb40ae9fbf12736af12 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 12 Jan 2021 18:25:03 -0500 Subject: [PATCH 003/175] Visualize interface position --- examples/phase/binary.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 76d4992207..723ddd3214 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -465,7 +465,15 @@ def deltaChemPot(phase, C, T): module: fipy.viewers >>> if __name__ == '__main__': -... viewer = Viewer(vars=(phase, C, sharp), +... from matplotlib import pyplot as plt +... fig = plt.figure(constrained_layout=True, figsize=[4, 6]) +... gs = fig.add_gridspec(ncols=1, nrows=3) +... viewax = fig.add_subplot(gs[1:, 0]) +... viewax.set_xlabel(r"$x / \mathrm{cm}$") +... posax = fig.add_subplot(gs[0, 0], sharex=viewax) +... posax.set_ylabel(r"$t / \mathrm{s}$") +... posax.label_outer() +... viewer = Viewer(vars=(phase, C, sharp), axes=viewax, ... datamin=0., datamax=1.) ... viewer.plot() @@ -595,6 +603,17 @@ def deltaChemPot(phase, C, T): >>> t = viewer.axes.text(0.00025, 0.2, "t = 0") +>>> def tanhResiduals(p, y, x): +>>> x0, d = p +>>> return y - 0.5 * (1 - numerix.tanh((x - x0) / (2*d))) +>>> from scipy.optimize import leastsq # doctest: +SCIPY +>>> x = mesh.cellCenters[0] + +>>> positions = [0.001] +>>> times = [1e-5] +>>> posax.set_ylim(dt, totaltime) +>>> line, = posax.semilogy(positions, times, color="blue") +>>> bug, = posax.semilogy([], [], linestyle="", marker="o", color="red") >>> for outer in SquareStepper(start=0., stop=totaltime, size=dt): ... #print(outer.size) ... for inner in PIDStepper(start=outer.begin, stop=outer.end, size=dt): #, maxStep=2.5): @@ -616,7 +635,14 @@ def deltaChemPot(phase, C, T): ... dt = inner.want ... outer.succeeded(value=None, error=1.) ... if __name__ == '__main__': -... t.set_text("t = {:f}".format(outer.end)) +... if posax is not None: +... (x0_fit, d_fit), msg = leastsq(tanhResiduals, [L/2., deltaA], +... args=(phase.globalValue, x.globalValue)) # doctest: +SCIPY +... positions.append(x0_fit) +... times.append(outer.end) +... line.set_data(positions, times) +... bug.set_data([positions[-1]], [times[-1]]) +... t.set_text(r"$t = {:f}\,\mathrm{{s}}$".format(outer.end)) ... viewer.plot(filename="binary-{}.png".format(outer.end)) >>> print(solve, "total solves") From 665c04dca29ed8aa4d31e54eaf7ea47c5085edd8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 12 Jan 2021 18:26:03 -0500 Subject: [PATCH 004/175] Add discussion of binary phase field behavior --- examples/phase/binary.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 723ddd3214..efa11d25b5 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -662,6 +662,26 @@ def deltaChemPot(phase, C, T): could again verify the final concentrations and phase fraction against the expected values. +The interface moves :math:`\approx 3.4\,\mathrm{\mu m}` in +:math:`80\,\mathrm{ms}`, driven by diffusion in the liquid phase +(:math:`(10\,\mathrm{\mu m})^2 / (10^{-5}\,\mathrm{cm^2/s}) = 0.1 s` is a +rough estimate of how long this process should take). For the next +:math:`20\,\mathrm{s}`, the interface stalls while the solute step trapped +in the solid phase diffuses outward (:math:`(3.4\,\mathrm{\mu m})^2 / +(10^{-9}\,\mathrm{cm^2/s}) = \mathcal{O}(100\,\mathrm{s})`). Once the +solute gradient in the solid reaches the new position of the interface, the +solidification front begins to move, driven by diffusion in the solid. +When the solute in the solid becomes uniform, the interface stalls again +after :math:`\approx 4000\,\mathrm{s}`, having moved another +:math:`3.2\,\mathrm{\mu m}` (:math:`(17\,\mathrm{\mu m})^2 / +(10^{-9}\,\mathrm{cm^2/s}) = \mathcal{O}(3000\,\mathrm{s})`). After this +point, there is essentially no further motion of the interface and barely +perceptable changes in the concentration field. The fact that the +interface does not reach the predicted phase fraction is due to the fact +that this phase field model exhibits adsorption at the interface, resulting +in the bulk phases not having exactly the concentrations assumed in the +sharp interface treatment. + .. rubric:: Footnotes .. [#phi] We will find that we need to "sweep" this non-linear problem From 2b817050e31d5930fa42a510da752bcaca442c45 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 12 Jan 2021 18:27:38 -0500 Subject: [PATCH 005/175] Add mass conservation to step size control --- examples/phase/binary.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index efa11d25b5..bb465c8051 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -584,9 +584,6 @@ def deltaChemPot(phase, C, T): ... else: ... totaltime = 1e-4 ->>> phaseScale = 1e-3 ->>> diffScale = 1e-3 - >>> phase.updateOld() >>> C.updateOld() @@ -618,13 +615,15 @@ def deltaChemPot(phase, C, T): ... #print(outer.size) ... for inner in PIDStepper(start=outer.begin, stop=outer.end, size=dt): #, maxStep=2.5): ... # print("step", inner.begin, inner.size) -... for sweep in range(5): -... phaseRes = phaseEq.sweep(var=phase, dt=inner.size) / phaseScale -... diffRes = diffusionEq.sweep(var=C, dt=inner.size, solver=solver) / diffScale +... for sweep in range(2): +... phaseRes = phaseEq.sweep(var=phase, dt=inner.size) +... diffRes = diffusionEq.sweep(var=C, dt=inner.size, solver=solver) ... # print(" ", sweep, phaseRes, diffRes) ... solve += 1 -... res = max(phaseRes, diffRes) -... if inner.succeeded(error=res, value=None): +... err = max(phaseRes / 1e-3, +... diffRes / 1e-3, +... abs(C.cellVolumeAverage.value - 0.5) / 1e-6) +... if inner.succeeded(error=err, value=None): ... phase.updateOld() ... C.updateOld() ... #print("", inner.size) From bc4e900aef3bb3f01f704c0fcddffc6333344d71 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 12 Jan 2021 18:28:37 -0500 Subject: [PATCH 006/175] Reduce simulation time It's done for all intents and purposes --- examples/phase/binary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index bb465c8051..bc3ddf52a8 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -580,7 +580,7 @@ def deltaChemPot(phase, C, T): >>> dt = 1.e-5 >>> if __name__ == '__main__': -... totaltime = 1e10 +... totaltime = 300 * 3600 # 300 h ... else: ... totaltime = 1e-4 From 4edca5a780fa74298a9544c362326bb40545cff1 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 27 Jan 2021 14:22:10 -0500 Subject: [PATCH 007/175] Create a custom viewer --- examples/phase/binary.py | 242 +++++++++++++++++++++++++-------------- 1 file changed, 153 insertions(+), 89 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index bc3ddf52a8..1f0d1fb58d 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -461,20 +461,70 @@ def deltaChemPot(phase, C, T): >>> sharp.setValue(Cs, where=x < L * fraction) >>> sharp.setValue(Cl, where=x >= L * fraction) +>>> elapsed = Variable(value=0.) # s + .. index:: module: fipy.viewers >>> if __name__ == '__main__': -... from matplotlib import pyplot as plt -... fig = plt.figure(constrained_layout=True, figsize=[4, 6]) -... gs = fig.add_gridspec(ncols=1, nrows=3) -... viewax = fig.add_subplot(gs[1:, 0]) -... viewax.set_xlabel(r"$x / \mathrm{cm}$") -... posax = fig.add_subplot(gs[0, 0], sharex=viewax) -... posax.set_ylabel(r"$t / \mathrm{s}$") -... posax.label_outer() -... viewer = Viewer(vars=(phase, C, sharp), axes=viewax, -... datamin=0., datamax=1.) +... try: +... from fipy import Matplotlib1DViewer +... from scipy.optimize import leastsq # doctest: +SCIPY +... from matplotlib import pyplot as plt +... +... class PhaseViewer(Matplotlib1DViewer): +... def __init__(self, phase, C, sharp, elapsed, title=None, +... tmin=None, tmax=None, **kwlimits): +... self.phase = phase +... self.x = self.phase.mesh.cellCenters[0] +... self.elapsed = elapsed +... +... fig = plt.figure(constrained_layout=True, figsize=[4, 6]) +... gs = fig.add_gridspec(ncols=1, nrows=3) +... self.viewax = fig.add_subplot(gs[1:, 0]) +... self.viewax.set_xlabel(r"$x / \mathrm{cm}$") +... self.posax = fig.add_subplot(gs[0, 0], sharex=self.viewax) +... self.posax.set_ylabel(r"$t / \mathrm{s}$") +... self.posax.label_outer() +... self.posax.set_ylim(tmin, tmax) +... +... self.times = [] +... self.positions = [] +... self.line, = self.posax.semilogy([0.], [0.], +... color="blue") +... self.bug, = self.posax.semilogy([], [], +... linestyle="", marker="o", color="red") +... +... super(PhaseViewer, self).__init__(vars=(phase, C, sharp), +... axes=self.viewax, +... **kwlimits) +... +... self.timer = self.viewax.text(0.00025, 0.2, "t = 0") +... +... @staticmethod +... def tanhResiduals(p, y, x): +... x0, d = p +... return y - 0.5 * (1 - numerix.tanh((x - x0) / (2*d))) +... +... def _plot(self): +... (x0_fit, d_fit), msg = leastsq(self.tanhResiduals, [L/2., deltaA], +... args=(self.phase.globalValue, +... self.x.globalValue)) +... self.positions.append(x0_fit) +... self.times.append(float(self.elapsed)) +... self.line.set_data(self.positions, self.times) +... self.bug.set_data([self.positions[-1]], [self.times[-1]]) +... +... self.timer.set_text(r"$t = {:f}\\,\\mathrm{{s}}$".format(float(self.elapsed))) +... +... super(PhaseViewer, self)._plot() +... +... viewer = PhaseViewer(phase=phase, C=C, sharp=sharp, +... elapsed=elapsed, tmin=1e-5, tmax=300 * 3600, +... datamin=0., datamax=1.) +... except ImportError: +... viewer = Viewer(vars=(phase, C, sharp), +... datamin=0., datamax=1.) ... viewer.plot() Because the phase field interface will not move, and because we've seen in @@ -561,14 +611,14 @@ def deltaChemPot(phase, C, T): \\vec{u}_\\phi &= \\frac{D_\\phi}{C} \\nabla \\phi \\\\ &\\approx - \\frac{Dl \\frac{1}{2} V_m}{R T} + \\frac{D_l \\frac{1}{2} V_m}{R T} \\left[ \\frac{L_B\\left(T - T_M^B\\right)}{T_M^B} - \\frac{L_A\\left(T - T_M^A\\right)}{T_M^A} \\right] \\frac{1}{\\Delta x} \\\\ &\\approx - \\frac{Dl \\frac{1}{2} V_m}{R T} + \\frac{D_l \\frac{1}{2} V_m}{R T} \\left(L_B + L_A\\right) \\frac{T_M^A - T_M^B}{T_M^A + T_M^B} \\frac{1}{\\Delta x} \\\\ @@ -577,109 +627,121 @@ def deltaChemPot(phase, C, T): To get a :math:`\\text{CFL} = \\vec{u}_\\phi \\Delta t / \\Delta x < 1`, we need a time step of about :math:`\\unit{10^{-5}}{\\second}`. ->>> dt = 1.e-5 +>>> dt0 = 1.e-5 + +>>> from builtins import range +>>> for i in range(8): +... phase.updateOld() +... C.updateOld() +... phaseRes = 1e+10 +... diffRes = 1e+10 +... while phaseRes > 1e-3 or diffRes > 1e-3: +... phaseRes = phaseEq.sweep(var=phase, dt=dt0) +... diffRes = diffusionEq.sweep(var=C, dt=dt0, solver=solver) +... elapsed.value = (i + 1) * dt0 +... if __name__ == '__main__': +... viewer.plot() +>>> from fipy import input >>> if __name__ == '__main__': -... totaltime = 300 * 3600 # 300 h -... else: -... totaltime = 1e-4 +... input("Moving phase field. Press to proceed...") + +We see that the composition on either side of the interface approaches the +sharp-interface solidus and liquidus, but it will take a great many more +timesteps to reach equilibrium. If we waited sufficiently long, we +could again verify the final concentrations and phase fraction against the +expected values. + +We can estimate the time to equlibration by examining the time for the +diffusion field to become uniform. In the liquid, this will take +:math:`\\mathcal{O}((\\unit{10}{\\micro\\meter})^2 / D_l) = +\\unit{0.1}{\\second}` and in the solid +:math:`\\mathcal{O}((\\unit{10}{\\micro\\meter})^2 / D_s) = +\\unit{1000}{\\second}`. + +Not wanting to take a hundred-million steps, we employ adaptive time +stepping, using the steppyingstounes package. This package takes care of +many of the messy details of stepping, like ???, while keeping the +structure of our solve loop largely intact. + +>>> from steppyngstounes import SequenceStepper, PIDStepper +>>> from itertools import count + +Assuming the process is dominated by diffusion, we can take steps that +increase parabolically. +Since we're unsure if diffusion is the only process controlling dynamics, +we take each parabolic step with an adaptive stepper that uses a `PID +controller`_ to keep the equation residuals and mass conservation within +acceptable limits. The total number of solves is not strongly sensitive to +the number of sweeps, but two sweeps seems to be both sufficient and +efficient. + +We'll only advance the step if it's successful, so we need to update the +old values before we get started. >>> phase.updateOld() >>> C.updateOld() ->>> from steppyngstounes import PIDStepper, ScaledStepper, FixedStepper, PseudoRKQSStepper - ->>> class SquareStepper(FixedStepper): -... def _adaptStep(self): -... dt = (self.current - self.start) -... if dt == 0: -... dt = super(FixedStepper, self)._adaptStep() -... return dt - ->>> solve = 0 - ->>> t = viewer.axes.text(0.00025, 0.2, "t = 0") - ->>> def tanhResiduals(p, y, x): ->>> x0, d = p ->>> return y - 0.5 * (1 - numerix.tanh((x - x0) / (2*d))) ->>> from scipy.optimize import leastsq # doctest: +SCIPY ->>> x = mesh.cellCenters[0] - ->>> positions = [0.001] ->>> times = [1e-5] ->>> posax.set_ylim(dt, totaltime) ->>> line, = posax.semilogy(positions, times, color="blue") ->>> bug, = posax.semilogy([], [], linestyle="", marker="o", color="red") ->>> for outer in SquareStepper(start=0., stop=totaltime, size=dt): -... #print(outer.size) -... for inner in PIDStepper(start=outer.begin, stop=outer.end, size=dt): #, maxStep=2.5): -... # print("step", inner.begin, inner.size) +>>> if __name__ == '__main__': +... totaltime = 300 * 3600 # 300 h +... else: +... totaltime = 32e-5 # 320 us + +>>> dt = dt0 + +>>> for checkpoint in SequenceStepper(start=float(elapsed), stop=totaltime, +... sizes=(dt0 * 2**(n/2) for n in count(7))): +... for step in PIDStepper(start=checkpoint.begin, +... stop=checkpoint.end, +... size=dt): ... for sweep in range(2): -... phaseRes = phaseEq.sweep(var=phase, dt=inner.size) -... diffRes = diffusionEq.sweep(var=C, dt=inner.size, solver=solver) -... # print(" ", sweep, phaseRes, diffRes) -... solve += 1 +... phaseRes = phaseEq.sweep(var=phase, dt=step.size) +... diffRes = diffusionEq.sweep(var=C, dt=step.size, solver=solver) ... err = max(phaseRes / 1e-3, ... diffRes / 1e-3, ... abs(C.cellVolumeAverage.value - 0.5) / 1e-6) -... if inner.succeeded(error=err, value=None): +... if step.succeeded(error=err): ... phase.updateOld() ... C.updateOld() -... #print("", inner.size) +... elapsed.value = step.end ... else: -... #print("", inner.size, "FAILED", phaseRes, diffRes) ... phase.value = phase.old ... C.value = C.old -... dt = inner.want -... outer.succeeded(value=None, error=1.) +... # the last step might have been smaller than possible, +... # if it was near the end of the checkpoint range +... dt = step.want +... checkpoint.succeeded() ... if __name__ == '__main__': -... if posax is not None: -... (x0_fit, d_fit), msg = leastsq(tanhResiduals, [L/2., deltaA], -... args=(phase.globalValue, x.globalValue)) # doctest: +SCIPY -... positions.append(x0_fit) -... times.append(outer.end) -... line.set_data(positions, times) -... bug.set_data([positions[-1]], [times[-1]]) -... t.set_text(r"$t = {:f}\,\mathrm{{s}}$".format(outer.end)) -... viewer.plot(filename="binary-{}.png".format(outer.end)) - ->>> print(solve, "total solves") +... viewer.plot() >>> from fipy import input >>> if __name__ == '__main__': -... input("Moving phase field. Press to proceed...") +... input("Re-equilbrated phase field. Press to proceed...") .. image:: binary/moving.* :width: 90% :align: center - :alt: phase and composition fields in during solidification, compared with final phase diagram concentrations - -We see that the composition on either side of the interface approach the -sharp-interface solidus and liquidus, but it will take a great many more -timesteps to reach equilibrium. If we waited sufficiently long, we -could again verify the final concentrations and phase fraction against the -expected values. - -The interface moves :math:`\approx 3.4\,\mathrm{\mu m}` in -:math:`80\,\mathrm{ms}`, driven by diffusion in the liquid phase -(:math:`(10\,\mathrm{\mu m})^2 / (10^{-5}\,\mathrm{cm^2/s}) = 0.1 s` is a -rough estimate of how long this process should take). For the next -:math:`20\,\mathrm{s}`, the interface stalls while the solute step trapped -in the solid phase diffuses outward (:math:`(3.4\,\mathrm{\mu m})^2 / -(10^{-9}\,\mathrm{cm^2/s}) = \mathcal{O}(100\,\mathrm{s})`). Once the -solute gradient in the solid reaches the new position of the interface, the -solidification front begins to move, driven by diffusion in the solid. -When the solute in the solid becomes uniform, the interface stalls again -after :math:`\approx 4000\,\mathrm{s}`, having moved another -:math:`3.2\,\mathrm{\mu m}` (:math:`(17\,\mathrm{\mu m})^2 / -(10^{-9}\,\mathrm{cm^2/s}) = \mathcal{O}(3000\,\mathrm{s})`). After this + :alt: phase and composition fields during solidification, compared with final phase diagram concentrations + +The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in +:math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid +phase (compare the estimate above of \\unit{0.1}{\\second}}). For the next +:math:`\\unit{20}{\\second}`, the interface stalls while the solute step +trapped in the solid phase diffuses outward +(:math:`(\\unis{3.4}{\\micro\\meter})^2 / D_s = +\mathcal{O}(\\unit{100}{\\second})`). Once the solute gradient in the +solid reaches the new position of the interface, the solidification front +begins to move, driven by diffusion in the solid. When the solute in the +solid becomes uniform, the interface stalls again after :math:`\\approx +\\unit{4000}{\\second}`, having moved another +:math:`\\unit{3.2}{\\micro\\meter}` (recall the estimate of +:math:`\\unit{1000}{\\second}` for equilibration in the solid). After this point, there is essentially no further motion of the interface and barely perceptable changes in the concentration field. The fact that the interface does not reach the predicted phase fraction is due to the fact -that this phase field model exhibits adsorption at the interface, resulting -in the bulk phases not having exactly the concentrations assumed in the -sharp interface treatment. +that this phase field model accounts for adsorption at the interface, +resulting in the bulk phases not having exactly the concentrations assumed +in the sharp interface treatment. .. rubric:: Footnotes @@ -693,6 +755,8 @@ def deltaChemPot(phase, C, T): as a :class:`~fipy.variables.variable.Variable` .. _CFL limit: http://en.wikipedia.org/wiki/Courant-Friedrichs-Lewy_condition + +.. _PID controller: https://en.wikipedia.org/wiki/PID_controller """ from __future__ import unicode_literals From 97b6b6f8e3c773321040e413fb9023df2921c58e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 27 Jan 2021 16:01:33 -0500 Subject: [PATCH 008/175] Correct description of time steps Time steps increase geometrically, not parabolically. Parabolically increasing timesteps (`dt0 * (n/2)**2`) do not perform as well. --- examples/phase/binary.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 1f0d1fb58d..0f520637d5 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -668,13 +668,12 @@ def deltaChemPot(phase, C, T): >>> from itertools import count Assuming the process is dominated by diffusion, we can take steps that -increase parabolically. -Since we're unsure if diffusion is the only process controlling dynamics, -we take each parabolic step with an adaptive stepper that uses a `PID -controller`_ to keep the equation residuals and mass conservation within -acceptable limits. The total number of solves is not strongly sensitive to -the number of sweeps, but two sweeps seems to be both sufficient and -efficient. +increase geometrically. Since we're unsure if diffusion is the only +process controlling dynamics, we take each increasing step with an adaptive +stepper that uses a `PID controller`_ to keep the equation residuals and +mass conservation within acceptable limits. The total number of solves is +not strongly sensitive to the number of sweeps, but two sweeps seems to be +both sufficient and efficient. We'll only advance the step if it's successful, so we need to update the old values before we get started. From fa4c4d45fd152ee63fe9895dcdad408b08c1d494 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 27 Jan 2021 16:03:24 -0500 Subject: [PATCH 009/175] Explain merits of steppyngstounes --- examples/phase/binary.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 0f520637d5..3f9ca74395 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -661,8 +661,9 @@ def deltaChemPot(phase, C, T): Not wanting to take a hundred-million steps, we employ adaptive time stepping, using the steppyingstounes package. This package takes care of -many of the messy details of stepping, like ???, while keeping the -structure of our solve loop largely intact. +many of the messy details of stepping, like overshoot, underflow, and step +size adaptation, while keeping the structure of our solve loop largely +intact. >>> from steppyngstounes import SequenceStepper, PIDStepper >>> from itertools import count From 875174a3360cdca4cb4be19f1c9e5fed53a787b1 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 27 Jan 2021 17:52:37 -0500 Subject: [PATCH 010/175] Apply steppyngstounes to binaryCoupled --- examples/phase/binary.py | 2 +- examples/phase/binaryCoupled.py | 177 ++++++++++++++++++++++++++++---- 2 files changed, 160 insertions(+), 19 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 3f9ca74395..2de11e87b7 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -699,7 +699,7 @@ def deltaChemPot(phase, C, T): ... diffRes = diffusionEq.sweep(var=C, dt=step.size, solver=solver) ... err = max(phaseRes / 1e-3, ... diffRes / 1e-3, -... abs(C.cellVolumeAverage.value - 0.5) / 1e-6) +... abs(Cavg.value - 0.5) / 1e-6) ... if step.succeeded(error=err): ... phase.updateOld() ... C.updateOld() diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index 6324ce3fa6..38d4ea6a31 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -479,12 +479,70 @@ def deltaChemPot(phase, C, T): >>> sharp.setValue(Cs, where=x < L * fraction) >>> sharp.setValue(Cl, where=x >= L * fraction) +>>> elapsed = Variable(value=0.) # s + .. index:: module: fipy.viewers >>> if __name__ == '__main__': -... viewer = Viewer(vars=(phase, C, sharp), -... datamin=0., datamax=1.) +... try: +... from fipy import Matplotlib1DViewer +... from scipy.optimize import leastsq # doctest: +SCIPY +... from matplotlib import pyplot as plt +... +... class PhaseViewer(Matplotlib1DViewer): +... def __init__(self, phase, C, sharp, elapsed, title=None, +... tmin=None, tmax=None, **kwlimits): +... self.phase = phase +... self.x = self.phase.mesh.cellCenters[0] +... self.elapsed = elapsed +... +... fig = plt.figure(constrained_layout=True, figsize=[4, 6]) +... gs = fig.add_gridspec(ncols=1, nrows=3) +... self.viewax = fig.add_subplot(gs[1:, 0]) +... self.viewax.set_xlabel(r"$x / \mathrm{cm}$") +... self.posax = fig.add_subplot(gs[0, 0], sharex=self.viewax) +... self.posax.set_ylabel(r"$t / \mathrm{s}$") +... self.posax.label_outer() +... self.posax.set_ylim(tmin, tmax) +... +... self.times = [] +... self.positions = [] +... self.line, = self.posax.semilogy([0.], [0.], +... color="blue") +... self.bug, = self.posax.semilogy([], [], +... linestyle="", marker="o", color="red") +... +... super(PhaseViewer, self).__init__(vars=(phase, C, sharp), +... axes=self.viewax, +... **kwlimits) +... +... self.timer = self.viewax.text(0.00025, 0.2, "t = 0") +... +... @staticmethod +... def tanhResiduals(p, y, x): +... x0, d = p +... return y - 0.5 * (1 - numerix.tanh((x - x0) / (2*d))) +... +... def _plot(self): +... (x0_fit, d_fit), msg = leastsq(self.tanhResiduals, [L/2., deltaA], +... args=(self.phase.globalValue, +... self.x.globalValue)) +... self.positions.append(x0_fit) +... self.times.append(float(self.elapsed)) +... self.line.set_data(self.positions, self.times) +... self.bug.set_data([self.positions[-1]], [self.times[-1]]) +... +... self.timer.set_text(r"$t = {:f}\\,\\mathrm{{s}}$".format(float(self.elapsed))) +... +... super(PhaseViewer, self)._plot() +... +... viewer = PhaseViewer(phase=phase, C=C, sharp=sharp, +... elapsed=elapsed, tmin=1e-5, tmax=300 * 3600, +... datamin=0., datamax=1.) +... except ImportError: +... viewer = Viewer(vars=(phase, C, sharp), +... datamin=0., datamax=1.) ... viewer.plot() Because the phase field interface will not move, and because we've seen in @@ -516,7 +574,7 @@ def deltaChemPot(phase, C, T): >>> initialRes = None >>> sweep = 0 ->>> while res > 1e-4 and sweep < 20: +>>> while res > 1e-8 and sweep < 100: ... res = eq.sweep(dt=dt, solver=solver) ... if initialRes is None: ... initialRes = res @@ -578,14 +636,14 @@ def deltaChemPot(phase, C, T): \\vec{u}_\\phi &= \\frac{D_\\phi}{C} \\nabla \\phi \\\\ &\\approx - \\frac{Dl \\frac{1}{2} V_m}{R T} + \\frac{D_l \\frac{1}{2} V_m}{R T} \\left[ \\frac{L_B\\left(T - T_M^B\\right)}{T_M^B} - \\frac{L_A\\left(T - T_M^A\\right)}{T_M^A} \\right] \\frac{1}{\\Delta x} \\\\ &\\approx - \\frac{Dl \\frac{1}{2} V_m}{R T} + \\frac{D_l \\frac{1}{2} V_m}{R T} \\left(L_B + L_A\\right) \\frac{T_M^A - T_M^B}{T_M^A + T_M^B} \\frac{1}{\\Delta x} \\\\ @@ -594,22 +652,18 @@ def deltaChemPot(phase, C, T): To get a :math:`\\text{CFL} = \\vec{u}_\\phi \\Delta t / \\Delta x < 1`, we need a time step of about :math:`\\unit{10^{-5}}{\\second}`. ->>> dt = 1.e-5 - ->>> if __name__ == '__main__': -... timesteps = 100 -... else: -... timesteps = 10 +>>> dt0 = 1.e-5 >>> from builtins import range ->>> for i in range(timesteps): +>>> for i in range(8): ... phase.updateOld() ... C.updateOld() ... res = 1e+10 ... sweep = 0 ... while res > 1e-3 and sweep < 20: -... res = eq.sweep(dt=dt, solver=solver) +... res = eq.sweep(dt=dt0, solver=solver) ... sweep += 1 +... elapsed.value = (i + 1) * dt0 ... if __name__ == '__main__': ... viewer.plot() @@ -617,16 +671,101 @@ def deltaChemPot(phase, C, T): >>> if __name__ == '__main__': ... input("Moving phase field. Press to proceed...") -.. image:: binary/moving.* - :width: 90% - :align: center - -We see that the composition on either side of the interface approach the +We see that the composition on either side of the interface approaches the sharp-interface solidus and liquidus, but it will take a great many more timesteps to reach equilibrium. If we waited sufficiently long, we could again verify the final concentrations and phase fraction against the expected values. +We can estimate the time to equlibration by examining the time for the +diffusion field to become uniform. In the liquid, this will take +:math:`\\mathcal{O}((\\unit{10}{\\micro\\meter})^2 / D_l) = +\\unit{0.1}{\\second}` and in the solid +:math:`\\mathcal{O}((\\unit{10}{\\micro\\meter})^2 / D_s) = +\\unit{1000}{\\second}`. + +Not wanting to take a hundred-million steps, we employ adaptive time +stepping, using the steppyingstounes package. This package takes care of +many of the messy details of stepping, like overshoot, underflow, and step +size adaptation, while keeping the structure of our solve loop largely +intact. + +>>> from steppyngstounes import SequenceStepper, PIDStepper +>>> from itertools import count + +Assuming the process is dominated by diffusion, we can take steps that +increase geometrically. Since we're unsure if diffusion is the only +process controlling dynamics, we take each increasing step with an adaptive +stepper that uses a `PID controller`_ to keep the equation residuals and +mass conservation within acceptable limits. The total number of solves is +not strongly sensitive to the number of sweeps, but two sweeps seems to be +both sufficient and efficient. + +We'll only advance the step if it's successful, so we need to update the +old values before we get started. + +>>> phase.updateOld() +>>> C.updateOld() + +>>> if __name__ == '__main__': +... totaltime = 300 * 3600 # 300 h +... else: +... totaltime = 32e-5 # 320 us + +>>> dt = dt0 + +>>> for checkpoint in SequenceStepper(start=float(elapsed), stop=totaltime, +... sizes=(dt0 * 2**(n/2) for n in count(7))): +... for step in PIDStepper(start=checkpoint.begin, +... stop=checkpoint.end, +... size=dt): +... for sweep in range(2): +... res = eq.sweep(dt=step.size, solver=solver) +... err = max(res / 1e-3, +... abs(Cavg.value - 0.5) / 1e-6) +... if step.succeeded(error=err): +... phase.updateOld() +... C.updateOld() +... elapsed.value = step.end +... else: +... phase.value = phase.old +... C.value = C.old +... # the last step might have been smaller than possible, +... # if it was near the end of the checkpoint range +... dt = step.want +... checkpoint.succeeded() +... if __name__ == '__main__': +... viewer.plot() + +>>> from fipy import input +>>> if __name__ == '__main__': +... input("Re-equilbrated phase field. Press to proceed...") + +.. image:: binary/moving.* + :width: 90% + :align: center + :alt: phase and composition fields during solidification, compared with final phase diagram concentrations + +The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in +:math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid +phase (compare the estimate above of \\unit{0.1}{\\second}}). For the next +:math:`\\unit{20}{\\second}`, the interface stalls while the solute step +trapped in the solid phase diffuses outward +(:math:`(\\unis{3.4}{\\micro\\meter})^2 / D_s = +\mathcal{O}(\\unit{100}{\\second})`). Once the solute gradient in the +solid reaches the new position of the interface, the solidification front +begins to move, driven by diffusion in the solid. When the solute in the +solid becomes uniform, the interface stalls again after :math:`\\approx +\\unit{4000}{\\second}`, having moved another +:math:`\\unit{3.2}{\\micro\\meter}` (recall the estimate of +:math:`\\unit{1000}{\\second}` for equilibration in the solid). After this +point, there is essentially no further motion of the interface and barely +perceptable changes in the concentration field. The fact that the +interface does not reach the predicted phase fraction is due to the fact +that this phase field model accounts for adsorption at the interface, +resulting in the bulk phases not having exactly the concentrations assumed +in the sharp interface treatment. + .. rubric:: Footnotes .. [#phi] We will find that we need to "sweep" this non-linear problem @@ -639,6 +778,8 @@ def deltaChemPot(phase, C, T): as a :class:`~fipy.variables.variable.Variable` .. _CFL limit: http://en.wikipedia.org/wiki/Courant-Friedrichs-Lewy_condition + +.. _PID controller: https://en.wikipedia.org/wiki/PID_controller """ from __future__ import unicode_literals From 3656079e9faa19f8c7bff0f3ba38f5255e809fc1 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 27 Jan 2021 22:40:07 -0500 Subject: [PATCH 011/175] Update figures for binary phase field examples --- examples/phase/binary.py | 17 ++++++++++----- examples/phase/binaryCoupled.py | 20 ++++++++++++------ .../generated/binary/binary-0.000899.pdf | Bin 0 -> 14697 bytes .../generated/binary/binary-0.000899.png | Bin 0 -> 20239 bytes .../binary/binary-1080000.000000.pdf | Bin 0 -> 14374 bytes .../binary/binary-1080000.000000.png | Bin 0 -> 20878 bytes .../generated/binary/binary-8.949963.pdf | Bin 0 -> 15379 bytes .../generated/binary/binary-8.949963.png | Bin 0 -> 21173 bytes .../binary/binaryCoupled-0.000899.pdf | Bin 0 -> 14655 bytes .../binary/binaryCoupled-0.000899.png | Bin 0 -> 20140 bytes .../binary/binaryCoupled-1080000.000000.pdf | Bin 0 -> 14364 bytes .../binary/binaryCoupled-1080000.000000.png | Bin 0 -> 20888 bytes .../binary/binaryCoupled-8.949963.pdf | Bin 0 -> 15373 bytes .../binary/binaryCoupled-8.949963.png | Bin 0 -> 21133 bytes .../generated/binary/coupled-stationary.pdf | Bin 0 -> 13931 bytes .../generated/binary/coupled-stationary.png | Bin 0 -> 18433 bytes examples/phase/generated/binary/moving.pdf | Bin 20847 -> 0 bytes examples/phase/generated/binary/moving.png | Bin 37747 -> 0 bytes .../phase/generated/binary/stationary.pdf | Bin 20419 -> 13940 bytes .../phase/generated/binary/stationary.png | Bin 36201 -> 18446 bytes examples/phase/index.rst | 1 + 21 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 examples/phase/generated/binary/binary-0.000899.pdf create mode 100644 examples/phase/generated/binary/binary-0.000899.png create mode 100644 examples/phase/generated/binary/binary-1080000.000000.pdf create mode 100644 examples/phase/generated/binary/binary-1080000.000000.png create mode 100644 examples/phase/generated/binary/binary-8.949963.pdf create mode 100644 examples/phase/generated/binary/binary-8.949963.png create mode 100644 examples/phase/generated/binary/binaryCoupled-0.000899.pdf create mode 100644 examples/phase/generated/binary/binaryCoupled-0.000899.png create mode 100644 examples/phase/generated/binary/binaryCoupled-1080000.000000.pdf create mode 100644 examples/phase/generated/binary/binaryCoupled-1080000.000000.png create mode 100644 examples/phase/generated/binary/binaryCoupled-8.949963.pdf create mode 100644 examples/phase/generated/binary/binaryCoupled-8.949963.png create mode 100644 examples/phase/generated/binary/coupled-stationary.pdf create mode 100644 examples/phase/generated/binary/coupled-stationary.png delete mode 100644 examples/phase/generated/binary/moving.pdf delete mode 100644 examples/phase/generated/binary/moving.png diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 2de11e87b7..7f5103373a 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -563,7 +563,7 @@ def deltaChemPot(phase, C, T): ... input("Stationary phase field. Press to proceed...") .. image:: binary/stationary.* - :width: 90% + :width: 50% :align: center :alt: phase and composition fields in equilibrium, compared with phase diagram concentrations @@ -718,10 +718,17 @@ def deltaChemPot(phase, C, T): >>> if __name__ == '__main__': ... input("Re-equilbrated phase field. Press to proceed...") -.. image:: binary/moving.* - :width: 90% - :align: center - :alt: phase and composition fields during solidification, compared with final phase diagram concentrations +.. image:: binary/binary-0.000899.* + :width: 30% + :alt: phase and composition fields at t=0.000899, compared with final phase diagram concentrations + +.. image:: binary/binary-8.949963.* + :width: 30% + :alt: phase and composition fields at t=8.949963, compared with final phase diagram concentrations + +.. image:: binary/binary-1080000.000000.* + :width: 30% + :alt: phase and composition fields at t=1080000, compared with final phase diagram concentrations The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in :math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index 38d4ea6a31..a8fb83e1a6 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -586,9 +586,10 @@ def deltaChemPot(phase, C, T): ... viewer.plot() ... input("Stationary phase field. Press to proceed...") -.. image:: binary/stationary.* - :width: 90% +.. image:: binary/coupled-stationary.* + :width: 50% :align: center + :alt: phase and composition fields in equilibrium, compared with phase diagram concentrations We verify that the bulk phases have shifted to the predicted solidus and liquidus compositions @@ -741,10 +742,17 @@ def deltaChemPot(phase, C, T): >>> if __name__ == '__main__': ... input("Re-equilbrated phase field. Press to proceed...") -.. image:: binary/moving.* - :width: 90% - :align: center - :alt: phase and composition fields during solidification, compared with final phase diagram concentrations +.. image:: binary/binaryCoupled-0.000899.* + :width: 30% + :alt: phase and composition fields at t=0.000899, compared with final phase diagram concentrations + +.. image:: binary/binaryCoupled-8.949963.* + :width: 30% + :alt: phase and composition fields at t=8.949963, compared with final phase diagram concentrations + +.. image:: binary/binaryCoupled-1080000.000000.* + :width: 30% + :alt: phase and composition fields at t=1080000, compared with final phase diagram concentrations The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in :math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid diff --git a/examples/phase/generated/binary/binary-0.000899.pdf b/examples/phase/generated/binary/binary-0.000899.pdf new file mode 100644 index 0000000000000000000000000000000000000000..63a8fa3940aa555494094e2565a7acfb9becbac2 GIT binary patch literal 14697 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�=vX}66^wW!u{ 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 literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binary-0.000899.png b/examples/phase/generated/binary/binary-0.000899.png new file mode 100644 index 0000000000000000000000000000000000000000..6d2c5722b4e4b61204fb14a9c46a64018e046909 GIT binary patch literal 20239 zcmd74cRZJ2`#yf#Dl;Q{B|EY+lM#wU2#L(HiOlepy+S1+6q3lu-b6;pUfDZ)Wft*0 zZ$0Dl{d}J9AHU!0^&8LgdY-u5^SZC=JdfizkMj<_ab21CB;82_L5NjV6txfpD;hzt z^$77{i`sI22>c`AqNL|?)4|fk&E$avqHf~iXzSo&Yh}vfYVp9?%E4ZkAO6e7a^J

JIYgQs`Yz68>WbpqXNke!o=~Yz>XZQ^2 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 E2NKS03jhEB literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binary-1080000.000000.png b/examples/phase/generated/binary/binary-1080000.000000.png new file mode 100644 index 0000000000000000000000000000000000000000..36587e81c3f31ae7dd7f7a28ec1db5b539534400 GIT binary patch literal 20878 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

HDDu_$(v){p*h&oqv3| z@A4vM?y$Q%TU%tp0pg~fo*q;Y{JgvCT`HYvD$Ed*-U4We6}E_Ow)_HFlvc!=ak2XF zF}K!70`G%AX)C3m1zC<%&;eg5D9y&kc3V}|H!LhHaL6iIOW5uQHY!KQh)DjVUNCQD zp&zx`+8N_PXRoq9@3rA-r%vstaw6Gi$kTZ zKn<--#pwUc%&n>gS}zaOD#^X&I;d`I3frYaA^P9z&q+$suUy2Bd`FC>rqhCoe1gRm zsgS~7&T!2dPM^KHmEbZ$m|eWdBJR0;5d;=~hhH}*3V_tRdq3A}ck|I`mDKy2ubyxu zx&p7T%L`PQ!TL-mPW9d@5fFP%%a#aKr5tkhykoK0NXql>vRt@81aq;y(W{TJNJiZm z>ajv*&+q3}PCS)(1~L$oWMe>e*0;R8knb?9Jh7&cqw^VxpnUJc#|SkUM8@0*GGT;r zf;d)3#F)7KB!QmmI4+QUKN0m1$VYyIT7SHL4YnIX>6YL0IeDT=DF%%h4*lPY(+QhX z<>-_?NtE&cZOgFMpK!a~`@pEj0tlrL&O7fP!0tTH$@v+e9=}Bo_tyjo8lQti+S1Ze zTKFZxw*AGh#fsQ4q4xj0#K9+h@ayXH30no-Ncm6OkCn3Me-2wYKy$*1!%FtH|@Y%kHWW|5L)L>#vh`Hk?X`SikI>$CFk zkT83#lS@iTsX~+oAdcqI`dEXkUaP_4@xz0q!;6piT%&rucNayKM9e00Hohn?Jbj>oP2wDvh%{dELn(ViEh8> zj7?3?NJubLRaL3?+)!3-G>VW41jNV4q5QgLsMG=35D={TjVu3sj-Wp6P(U)kfSsDP z%KO?_+S%ZmQ#P&U%$fFLeK9i8OTrf2P#0ur=3{4Sv{3}Q252ihol<*T zM01F{)LlLLyE_vp{6B79J3G&Gyv2#;zW?OsPs57UmJ6tLtfEJq zY(PoUM#vm|vKxd9)3iKZhlK(h+R&@-9UjggVh9wrCe)6eUS9d`8|IIM=pE<#$fw(r zngHHj^w_k7`%Zx+2FYr9YYQLc2z=Urm!pG&AJiIgLS|}4G2I0wt%$_%HBOkw=YTiF z%*@Pnf1{TlHqnH;A0A2VTDuIHtoM~HB#-WHEh$2Q_D%ekvBdmB&LKnG^kwcQYNazV ziHT32Kc^sO6wMo$e)8l=*fVy3_R?F<#Ma)YmpWYfP`mJ zQAVo=Z{NOc99>vgK!giGhZDtDu3Wjb^BM~5aM&}ir97xFU%pHWLPeSLLWm->7Zt-L zOQ1dub%V~l9eoHiGEHfVsy1MPMLn>)6nP7Z(AI?c``4i5Y;SKbz2Q~NWJTP1h5b4FrU=a zv!H3wWZuiJ{rXDKZoZEna`=z3gx^0teq*>cEK(pPl8D2}XX>LF!h=p1qW2Pc&PYb2 z5HjR8odEEx5$5d9RB2m+#2I1XZdXHk6i|Z15)u+%%BX4!ngOP z8S3+!RW(u1pO5|g`2^$(REM`6#8w8V46eYYfJk&}vFY&{MMcG^d-6^QDSah~^cDAw z>(}L=)Op)&&c1M_|B{46_=-12u`G8JfV0=HUthEu5W1NlehOKI2YYKOj8g7Y$o{#b zB8AJr!6C1xIDwD=fHW=|)SdwM!gtq$6y6c{IUYoQ;801dC*rH{ff;5nY7E0dNgnR4 zfeiyP45jVro3J3~-nu8P3|U{OaHn zgn58^DSd#tE|jkdV^j49FSl}&9$^kD0KI8ex(n;M&%P61y3o(7N5pm-QtJbNiFqX@ zO`y}*9qhTedU%{UcMk7XoX}^;cfcs09rD^5e)K(+5DI{&5N5htooRTq{2?@-VQ0rJ z8GS5qWQG9^3Dxob7DIhg(*%GA1z@%z^zu8;YgX+1&P1U!G&B&=6`}1PKb8hWkPo33 zSde?=*)e+Vgy7FWC=Mje0+!*LL%=|i=PKdD_QddBJr5En0AppmtC|TN)tIvr@OoQt z6%DSvA@6p=&b)g|B&OPZgG)d_0F6eYVA@}CeI!X!Nm7uNMX9N&bwCkQ+G=)tPp7Y{ zM$F^3rdl8l-kXs4^LsVSVmU$geQEEjDxe6SuNV@BGC6yOX#Chuu3{tsyP!k1b zWIk@KK?SuD2<>;ndC;>^Xs4QMWsfrwC>q=kLDK2NSh7%#PM#*nq3RQ2e;px-&vqI~ zunRj*ERy(!oOqa!VOI?qwjx6!d2tZN)9G{NV}OR-xK3bTukXP2PB5(2kf`3C7=3CR zfrC(|Bk;Vg4hMpNb+eQ#V)cOsgnYtRv5XDFd+537Mnv0VcpuHI+Hdjm^y=mC{(JB6EYx;hxbqU5<=X+AQDgxF~}G zlBhXfjkb~)guSf%M5MK?t&vhi(wF^4^cbkV3Q%W*;t_r)e15Qm44zA0i48Lp8DwF! z{Mg9pK|jDjo#)|cu*j_h$ypqPTl_okZ+?b72_mOWK|=bSw4dQ3BQ;hf!-2oP#ZT1u z;y{fevkbEA7{o+meIVv38a-DmX26B}Oz33syk7b?-{rGq?`T;lbUDkP=rM0RHyLb7 zlngxgaHI$JC4-5H2__`u3Fv~T*rE0cFbN>5{i7C-xbr*)n8As7n<{=h%sAd{)KPUb z)$($tzmNmGMx9yr1t%OpifzInlYCIH0IB9@<<`g*P^7R>NQ44lhpbkB=GO+@lHD8U zWK)f3?wz3lM}RL5elnyDL^scejI_7EHQG2`?l@~`FQEY%WE5}4ix*TNCsG|89N5~~ zU9Nt-k3vBOe{PVFkTAW#3J3-xR}_*=fpT1)%dPI|T_o?OgT>uMjgfELY!ls_hFKzEIYda1ZK@5^HUGoUI!aBtrtm%ipFN;c0LL#@#6v3($!V8wytgk_&cNw z{_^#!JdiBcZ``=0*Za|ILF6aDWBIGWeFbBZqs1xD7Or6AEb@E^YCd<) zl)R(Kae-FYqQSu0>P1<(vXUTcEYzfIY#!&M#dfdXt$3Mf*pWnD4v$uQ&gx|N< zqRt_}txH8F9Nb+O)H849cZCJk)zHryk;v#x^Q#B}Xu<@&XZ<)qC3SBudl`xv%R zBt)h3QGY@31jN%Y1`$$3xLciS1*Og)DD%-GBf0UsZqkj)4q z?3l7CXV5C2B_-LczS-e-S=50#t3?-2HCy!L4e_gZn9tvOLAkefBe@Kv_&Md*7@(id zh>6ibbaaY{;u)~$%pP`~*2_!R@%jO+5hKT~5IfxP-3{zBUNhK9E;OCzq}ap;7S z8Wua^)x$GM;3sd59dKco(B!!3@htrV>dZDY{0}B zUbpP*_~++ux-?z98iejXY?VvvLR8O5)p+ennsiDTvSP5F%)&IH5WWovCH(kHR&ws{ z;z%V6Tf!*j2VCx=`H%AxJ76yQ{PeU$p7Vm%YjLNONcmYGOxamzsxtAi!^wakB|dGL z#pwbsFWzmZ>$C-@UlZLBZ%{T7Fsvt-1Y!4J@6TU!@z05gaKV;`rl#>XXG8!xQc+Po z0C%eEN&`)2g_{F0?L`#qtDG43`Gtkf)N7OoBmlBeT}vXB7pNN=nlli7VYQ3AdiLBh zw0QN<1kg(wxuqY&)bw=Sw{Ik1?&)?meHk4MELojsKZ`0LqVcJz20}KgKJDFunmLch z4Mwb1`IC_>Kp>V4z+z19qsCB(iHrYilUOnqp~mWP(axVT*qwJHl^4Ln1i%gez2&S6 zo%~&ukFb8|Bvyl!y8EyrA=N>qwDh&*L^#gR=R(jaLXY&Ay?C_rbr-!j0~1#7}%4efi*Q#u^)YDCvf#R#nbCu zJ5PsP`I{&WHD$fw(G{RZLDKw7K^^?szXta0X`1ZWqo10&vX>bj9aeW&bH28K@#xn% ztJ=?248)L>ABQ(z`y7D`zZ?JSa^fz>murlgDY$14e>CF23!P#o|C)}(Ba|SY0l#>M zT%`;K*nD&pz4H6x0ft9$UOxsO#v$L2=2kRJnI!m*7d1`-kpl#P-%=4 zw&*B#vB}adA&rcTRJw5kXaxPDT(|lBre!Gf3?>@Gfozh1a>);bh6@_X^2PozIca^U z`~TU&omp^z6p6qCjQvQz0~$R(>Z3((TO2!OBuT-!8M}^HwuO{&(?ci{#&e+Mq(xG0~m%`e*ybPEvuJ33Wyc!Ua&7%Xa+u-;eZou zq5u;3Wdh$q({>~nWUbO487MTW8z>{K#yQb27ua@=j`E00hJxZ|G{@PqEZp2#1HFjB z1*&O91B17A{h&SJA+;OO8<*$U*#=E!Y7KGf?IBDb=@Sx56@ItkFCiW=z>$}a%@3%V z@+5_DdJ~;PfQ?{{$47iLKs1j7SVOV_|HH4e0G?Zm801rJoki9|3K?1jLgs6+eg1>> z&ijb(fWj(#PQ;>z7~om#MFVVjUSs3qzD-OX#E1J!-ctj(Yz0^%i5jPVHfj&4SqVLf zv_L#E$EG~U7V3-km@g*}c)1#Mb7#w24>i$*9@&Nx59#H>ocF^i6^vwtE#w=uB3ip^LV zH{#QM|9!<6pAYOgW8FE%5r6AL73#`g8BwImoAQGey?JLjN_@EllhS(13ayWVEY#g| z6Vg^DuKrK)bp~UduDP3yn~mv6>cszfV=u7D|>yc>jf#OtXN*=^~A(ZC@oYbLj?a95-FJe$A#s$W?a_;z}=+pH` zXt{e5h2k38<8ik#bK^wSsJ22(Q9B()jmb3GA{97+QO;~*=sJpULiBIKe^H=jbu~$~ zg4}akss9=?iOy|e)Q1k?l9{4+r@-w_o~}h1Ud66D-cg_2n@<#qQJRXA^PVcTePrG_ zM~wCJK@-$}Z0Z8VvhzF^zO-$=2veG>b_&_pAw`ktmM#lF@bVbtpue~ePX^-vV*l$_tm?5L}J!fgQ! z={Mm_9|UA`YRGGAcT?8RijzmispBc}zviyuC>uWu$xU9~-0_x7__h3wx3#q=3~1m= zaWAQ{KUn%|?x;B%kdvotnwb!t5N|EdbCrPxoKuP!u4adSg{GzMyjk`j&Wrs?SIYNK<{GaVv9kfRQ&dHFn@nDIa(nKHa zPWM3GtdqZjt{xpu4@wKt7j-uRQpXXAUTE}03F(9CMj*n4P9EgLpH9aF{ljMN_2kH zHpar@JCKRNOB01po{om8LVN~LD!zz`sq5%A7?F9=&^tuVs8x-@bfKtB= zDC_7j4h;>3fwgc{ycd%0^v-$ia~O7j)_8%G+IVspu2$3=@TaRt|2Yc`K@gO1@%smY z55LOl=_Rg!D@A=eF8Ir49?=c@wS#nPlmB7J!}0;r7*tM15F}}39!sL$Bqw9b5rDhM z2#ROgiw|U9_Rczr&p4I^_7k!d&_SN0hdc=!AUQaBpv;b%g76O#L1sZ!X66Ou*P^~) z7@k0QvD4y?NJkR5C{41z2YaA94+gv0lGz{FDLR(Ad9{IB0=WsTj)?E=57E0hjAU9EYN`kViEDtet-pj z^z}!^fWMaf7Ea{x{xcN~ZaarL-ar6#Tl=y9+KqLt$X1K|P1o*w@iO<(E}FRJc)T&8 zmN*iumUfIo1ZWJ6jxVS^uzKC`h`8JM_;S=Ah&H;T-3uJb(Xb~@6aIBdZ2y!z?xW8H zU*nAL%O3wXK(_yW`iQ^BU`LxPbQEYHoE)DD0Q1ou<*2;>f;ygv|2ldly7>4@;%QmY zldZ>bYvlXAqgXPs(M)B+Ti3Qh&J8YZ z?wj12d2jSa1*N6+plRlgWM6fxUQwxBAxMhr7I@j@FSo6 zXv1iWZb*0clt%=XyT4_20d z@CXG%MQj!{1+X6g)cbE&X!`CoRBROwo0ke^2l_&EL6EskMNNILJcs8-^Pcv$%C6kH z-g@}ZJ560cdVK-i7_%ZR#J_+7Q(4ITye07KO~wh(?w1T2pRjbQqusxTSmV8N@F;Bm zinm!Fw5i4dJKu^Tat=_71m?WH_A7g3pD|&6`SIzy-B{@IK-6>44K4!(0fKApxc`uYtpFy6xH?a%lN8?W`{eNu-r9Di%WJM2; zuOr_`@llZ$1aqU$PjFp-26KFMXLcyQqYqD7kv-dJRvIXYe-Xfp4CX{%1`82CQ{ZK1 zpNa;lYH@K9DkPh{1qG6iys2+U1LHx>9LS;WN$=8qQ@ z%=g^^@n4HZAS2+BGGc(~2B!ly+zQh9)scKPlxuFFY_8;^$rDYvPF>CDFzWt%BYY;; zF|3c~-6w(lgOry2T{lGmY}CSdN>`i=ia?>z$}VoHwsf$!zj=VW2a>4K&ibq?xc?BQ z9ce8^$_pKx*Y}r<+MIt|oaWs9km|%eta!}5dcr>#V3%M2N7=Od)p{TeSq z26@lc(Xk%VPNr^eG+i!^0dus;?`g@$`%waHzaB!_NDVBHpvQjWrIR-ZSV4_xfPSd@ zQith!Py_DRENS1q%>obuVUtcTOddJMNMdmvWM{l@5ov zxE8XYM8jM_!Au5;2oX;oR!4{prsq1rY_a1J)81ZMvdDJ&>PF_5q8Jf^OGJ$U$xIKN z845@zQf+6aDhNltn=5%@-jh@Whi3X1Ylp2bu#bhy3@V^D2IEBtbPUCECyCl6e*!7% zn|s9Ssyz^(7vKs`txn(s;(~P>7Lk>er9i`SxI2329}y9OVu8Fox8Sw4FlZ_u*|!Yz z@}>Jr*(D3jQ#~3;} z5u(G<4X8@j}_q%78%}Rn-SO7THTHJ9D{4oyk{~R8*jcG&@t*6y$s` zjOe|b0)`HZNH42!uY+VGcCYNx)7hmj7Uw#q+7! zodqL+>*4+u)=ZrdfK<(VL)^vEX(pq&2C#9!*b5f$$vK%}JSlxBI)1|w_6`pG-UptD zwcz4KG;Etj&Qn0=-pV1oUt)c_rKM%LmWXdGfJW~kZv@B%fDp5FrOErz5|C{vu0E}O zenVH`3_5b5Oy_P06O`d!Rd^VUiK&DieS``WlXcmnZbo^er^oXsw|^rU^=Aw=kw!4X z2#9;Xg8m%g3TKfM1d4{QkdEREmkIw4z!iTV^Q=XJ@EP6FQGjfYAxWc{7Vve)rvy#q zbsJ#1H7HXtwskKS;kVElK~8R6!9k$S@(cJ*a;y&eMZ(%S*{=vGhCTKu_fVXh(}+2` z6izGuiHYSMF}e`>IZD)gLqDjuh3@!gz@308JNj~tqq9HYXe$0@ zMNibIYKxr=69=&oc+W1@GF16%>w!t5^?yE{^$?Sp>$U?cohWGa5udu6ukQhF6zIo9}Vck z^IQ)~lx)wG;j0Tr7f-%k#lwX&xpV<;i{a=3p2G=PsF={}s+zTLD~gV;Z*ONW8+vYs za(2G)sJxxQd(3nT3spT$)uI!;imVIkj=Eei)L40#jvG-v7Ti=a!}`f(pi?BA?*F>} zLZuU{0Q$)OGDadTNH=e0+3f>q$pTpgFwCcg;=yI`(rBlvv6*wb<9@1BPFbqmS;)mM zZB-R&!29x_x}5JX?9kEC(F#36BQL}NbrbQ_#EROn72AwjPqhFITlDBRX1PrdCV6WUmBzJwXA+hr-iBrziam2N=nS?ddVo@o8*E#Hg7%XZ( ziMc=c^}l?@;9S+(N?>7&U%&Eel(y;;p&aTC^SqDg&IlfUw&7u=E{D^fkwTj{alcbP zex&-#Qu+^#>z|JEOV&dekZfU2-h!z+x$#|)KG98DTaJ5=*Ce7n_b>D;?otl#$E6g7 zQpSncfqfY#TLDKR9M9Q#XH=NJG!suDU?;_mQZds?MCl6@)hQXm8FWxC-dC#Y@0(_>&N`0ds%x+0S6_*e!5c^jUDK!mQo!RI0b;b z6}ei5PHrg}=*hJ%1$4p);ZDP(G&eW*-8%~M=A1$M*<7CU=Y2pbyP6AyJK{A2oO9g* zgrBtQ7wT$STQdhXzy<{1Np->E;n!GSXhfbEh2Gaso__?uEo4rd5s!#LU;~DpOi33t z5~ieq7258wrnHAnV$z@@QBgsi(DZYGOW+?xGU5qsL<(hEamPnRxrFde4)D5I7g$1# zO+ZLkI`xO_xSOsZ3;cM`=bW9Krh>}xB&CZc_%rAtRKBG$G2hT;!V5Wl@89cbfY4DL zB}_*wuME`QP!wFYwB-KY)s=77boi}cmmD;h>dx?E~vGLNM1fX&JgDWD$)DE z4YA>LOP9c?xmppIFWe{@iH^EDWJZTyU(>&zR&f76cQGk09a8!18MGze%14?wl=_iP z{nwjvR84$@>V;Mif8cam!dvhMmO7XsT{%A&PO@GEVH995;$;M#aY1`h>K$g5FGv zn8Tu+xDSX4U-tjsBx~>AKR6NH5P?1jw1e($7U*ZH2NBp@hl7*z8dL%KU}TI;Oys5J z)j1CYP6LR|JOhgW!u>--L;I?{%0=yd`qT0o`hy5h4a5YAi>!6>zR`%amRB9+DPj)|Fd{cw#8n!l6x z({1ceCo!mRO?`OL9)WI=Qjl8~bWC~unh{GD;G!%6>w;iv1}}G=(29u4F0V=4HqurB zu5#fVBUcrN;&|wq0YhqRR!Y~b?I<{?3W|5$Pfi%+fgky!^)Njm{veIEaKcuXyKJRT zBg9@T|G|3U6-K;G_g(O-G!#yxvIC|{>R8{=UG=>mpN>m?>(3caV=w9!VP|GWVZy@d z5g7-x6KZ&yLj%xD5nzmsz1cka43^}t+qKj9Fr(PpbOLBO1f0PkCNsm;LYy-hFl>`;)DXW2xstqfg=g*^|WMgAzzluTwUyHm} zL_N^Ab^i~!TxpZiLeksmL=R8YBujNJJ(+Vp+FyTkcdEF)f9x)b8jj{`*+_}~>`$r;em zD}UGfA8`@^J&_2h|Nr|&u`ex15dzPq75pR#>8pWi^7iS_nGmD@I2epXt-2>w6Y_E8 z?y4X~5a`C^P7uxV$5qhezQ>8d6BshA?sZ+|5`Y zc-W*+Wt~Ti+F-9idSU>-$lKZFZ@9!Nwdich->rmR2OSu6{)5lhP&5*)04X0YIa=lA zkq;Y+)gKK}80;&-Bn+4C?&@s~yCi`nC}L#^RPN4?W_P0ENlZ*liBLb`wI(EaBJ#pu zSxk0c&-LCX0&buY1mrxIB|XR4?+x2JKrSJDRq!^LQKXfW5a<}!)-5Pe!3&&yj|iIP z!28_&>1&4;z^?QqUDk|KpqTyc1brFtumXb=?|2n!XE76@K-${cP!IO*Q`Sl4LYq-| zvjDh>WxaU=z6`)(*qDTXR+ADT9RfKF=}akn_)Wm=0D4a9u8>I?@9l!Z>|aFFm+$~?KVt~OQB&M=5Y1QF@2fQezb(v=epj1o?N@V?{)8Ct+m&^_gZ^@j-Z~3ngmJ`3lqHj0$y4R zL&1@74{K+btSlU%XXRk$4Mzit0UTiz;Asa(C|i-NTs<7%`}V=?+-;$X((4+i`jgZR zNme8~ICiy>nuj|Hj#(}1S&>L~M0Yq2dW0eLh#oeEb|knt7)M17^l#@+f+IBCz?e!u za^)Yn2K+D_Vd!XO>*VeL$FDXw)3tWCvmwEy$esUW2ZaQLH31ae-91R&UT7lZ~B$Iv5%}84<1Ay*;gncJ4L-Ym%?l2LmCr?QET_ zlsx=FztCW4X=ykXgNDY?gPM@mG-hDu?cqbT0V;%a^p6T5t*+A_#LgPOYEG^|MR0_g zE6|~eosEYrQ27BncL$Oq90kpc0o2f&M6|PVgZXDR9MtlDQM2{doayu!4?}L4yZtpI_7?B(64UM1 zYTI)L7Z+G&UQad_y!rU$lN8;sX!o(#3{4(QeY$3W(HuQdd*`;7|4JA2qS<|KjF9 zORWE#t`l zX7N@}>vA5emYkxF)Cf9SDe}%CU3W!9V*W)%X?509sUIKb$NL}HE<%5^JJY* zn(Q9;4>{HJa@H!VMq|OSEc9J^Z~n?>{qQJF6K_r^KhRaD4cPK`zQv zPof)%c8(Y=Fgla5bzt|wD|S&5;V5pl-sm?r5-V!AW%jUGXg+o}OmB*0-y*Mh-`UVf z#8>I)W_FF^GZ!#%bp=W4W&x}f>HH+v=`fb#Ry&e}o;@ws^a*O$hdYK>wTu~s#J^!LJLQXX%rIUdoieD_wv}`}(f_59fQ(`YIQL^P2*3eDp zO4Nd7@g|2wtj;9Qvt3LvZSU{yNPH`FZf2H#S+XxGJQR0Y4@rA61AC}Ri_b|v-I=sk z?Ir~eS1Jd-0q@k3-X?T2L1;45Zmc#nUZcqugI0f$hGj~VHG6`elqQy_9y(tqRa`iocJzgW-FTnw(Bb}y zum}n5$>9r5q6wBg2axKgBSX`h#TUw>>tlO0A6{(PDJP!V*jzF|q$zA_AI}Z%;-%FMiR{752osC-fN<&*m#-8p%y<(j&)oa4)zFHBFXYtK*Xze{+Q zmvwggtxxXDZMo*|sP>Qx1(mysTeqlCQsw4v8hL*r=}S)538|?Y)nlbH)#8^&S@S#! zY<7Nr-&I<7URm(D;Lr?3OpOiq>FJWT&lBulEmObYgU1bIjvlN3Ha{~p`Sivv`4`bm@) z?q1pdfN`J6-p>zP0z0^y{pP}seDq#&o+wXKp{I;3AUHil;m)P=A%hHuN5wQE$r4s}zyG|Q!_ zy`r})<7+~Njp-$~?O8UNaK9DpI!fLL$3{lEUwLrx8O7CNqYM$?R|b zJTkBr{1Br4)Q(wZ2Opkzsi$b4Ift1O{PbBo&*pcW*nMT^zSDK-iY_eYLWCm4QssCm zC=Tr}Q1t+7t_15TUH)53mX}0y=?Z9h(&wHUKg>D?vP{}P%yU-)w%1V=oY}W z7_bdXAsuuM@i=ja!Gh)DOhT};kZ|(vK!W| z(07=pf=YrjH&7`j=L-MVi6MefrlpQ4rL{$NwD{=skX>Y;M!3RpHTXl`3C1KRubK#c zoHo8Dn!b#uZ2YXaYFj>+mqeWRgK6aRj`!V*UhK7=vNbH$YPGad^!f`!Rb#5#Bx$yl zsTUfK)|}2ir2 zdqmbek;CfVlk{n~CVF#mu@{$;4+%VuIC1&283m3;^!$0Dhj#Bm)CI+w>Yo9ZQ*X-xd)HJhCc8= zx*OfX7Hx%E?TRD0yOzFnD@ zMfg4Ixbb4qX*{h(k~yukOs3{+!?b;QVBynO6aJRox1Lw-^lj?Y%DP-b41kd4BNioPfL zUg*0Fb>c$ymSwS5RV0h_Hh<8cb+*rc<6L;+R>(b*^aV~XTGh=$;tpcpb0{B=bM9o| zOq-PIsFM8zdrT7V42lY1Ruu@{^7fFsrQMbAoT!}{i`N}RRz`$_IQ_5nFuy8Q%Kd{r zAW#2qL?@tsl{~J3u@Om26;!xH&2JUw_Dopw?ZoSM62eYz=9!;9x*&bo%hwpYOZrr> zzt%!T{JrGD6m`SQm(Mww#KPI@o^f&>vD$iZ);Vn^z_70|$sqY{*XLt?axJAhYX86^ z6!xs~sAT1BM~;6$aN%ra;$sM63JG0nS0^tYD3EfrB0?dMHyrgNAX0S){yr4pKrxAm zlfAti6n}u|!5sMhcsPOtN1>5$gg+E$tOjHMwAi-~#0*YEZxYli90@}}<0`F&C=w_n zXf1)kq2MSy9tlSw@zPKiP!$zBZyTbMC&_~dN0Fnn)t1^;B%%{JypcpAp|At|{Zj%> z4_N&e35~m!#`UUBOr2~=jzIX;=yF~B2Jx|`LPc*I zD4rsq2~gzex!=yo!I1>sgV9#sNT4x5Gay`Y0C64uujT%~v#bHaTPGVucL!HHXdG=T ze=?&$Jvi`aNV0P?f#|FH-=IQ-**^@flLrzIlE)m5MR3C#!t>zdhsQ$kt*xGvxs0$^ikF|uu0P{ma z3XsNv1Ue!}!=qBQI2`B%kAX{JL0xIU01}j;9D0ud z39OM)pgq(lL7D*aRT`9&g~3R{pd4ZX5(-LqVCYa=91wi94^S73OD~C>92d zi34rON?BtL%E^`njf90BkdTTXwjt4=93=9*K*Oyj7!HU?ZVBo4X8|y{+68)bbR5JL z;C#&t)~0JM2U7-HV}#5VRtg0gtj;532fwfi$wW3LU{Fx2e|mwKLLy=0cRxBH;0fUC zTuqQ6tl9u%2frq=u7O=ZHnA>|?E$ihwM4d+A2tEm!}iza0}{kl0_hzoflMO-KgipsW*It#M0dN9JsW zQx?BZ?nAek9M_21B!cisuPl^>I|*uGqa7s>_w> z@wJsQ%_U99Ec5xI%u`X?XER3kXmQ`5&u+RFGnyK5k68*^MB@{$b(isFpW{JTm#5Fl z-Uju4Kb$Prd7}@#T&KD8Io>Vv>E=bh*BlC#72&f8LaK4Hju<{vNT{;7GJ8bn6Vr|D zm3I}LHAbt1WuN&3>PotEb+Itp-ZWa$(Vv)nfVnlHNhim8eb8(wWN${r`|anYCqh4} zJ!y|CbL0zcH5DEgw0vPGq{?cmbKT7SRA2T~u1KMGls7m0Lw{_P!8>cy(qjyJJ;V|H z;;qS@^k}t9+S$_nt)cN5^8qQN{@*BE=e+m+zNMqr???Zpcr-Aq^@npfeGPY@`1)~< zxv)(`lDAtFbthM@?tDaNY3Zny*|l}Yj;;PNcX|{@?wdb}%UC+!c6g>vmV=k>#tC74 zsv}WB{dAHZ+s=KH?hKwja)@wtyDl2e)jvP2(rS55VXSdtd#}}bC*jXg5j_d}aXSv` z9MyWDRmviw+aG#~UbFhjhn~qQ$?8cLUFrVGV&N2Bc(!@v=5z6;2RLoG=T+WHHqR@T zR7GY-%;p6%RW29tu^!IL3=`f$ldrJ1eDr!wjA`TrAD^7-@wwYYcj~U-u{aI>5jMfh z{zow;PEbbR|sp{3mE29|3<*2!6Ex(BeW&7<<8MrN{ zspc8UcSt_z5Nq1WMlFVlWRD?rHAOl4+gy=Dn0q~3k&4|B7ZoxWxLMNuqn@j|kNJ9b z*EeC}2%EW@4|x_oPXA=_Y$TILn5Ek-c_vP&R>O$H%P7a|z)VSHPyExcf@`i-kIzi- z#Ybpq2nwAGHQcjOEo#1J?71pi`Tmixv)b4}ae3t=>&^?w`isbG3G-f+XViTjwDo5a zB+~n*E=?W?W;PQ_*MBRTHHzLRTs&u?6Ean`^WjKdf$^8jZ?Ddz&hlRy$nAS?DyW|x z-*+joMs_7GXXZO)!i9t66ZBtwey~FSTo3+Dd(h6a-q_>}wA`stv;#e&H3|jO+QjVQ zS5q&KnV;`8DuE#=ucMOBF%%2Re@HrsIS{%)JUpa7+u-W#@Q!av5?{DvMm$;@^^Ev1 z!@5G3rw!3sZDf{f@-km}CQ^ird6UGOFzUfuJS#I?MR%T-M-rQYY&TnK_PQ(FSANL7 z|DfVlt1o9b#xCkzbshXD0ypiw9GOe9KFOH6N%U4JV@z66|Apv?l%$fKk7nX7PMhC3 z9Al+tZazTeZ~uU$|J9lJt(eJ&++GK_y2#7D&(}v^)8}T^b_kw%i8h#f2)cdL`m$Zw zp+`yBa`!upv{6ri!R!G=depqv)l^;A#WYcqGt<<2+bJj;zP(C{?+JP%9%nHyaX@(b zq0=QEwkx-It-poKyK0@cXc3E6WiP51p$&bi$mSJn*1Tw&ui{rt@kD^F&ry(tf%R_p zBy!gOen9^#j_P;wDvtRoyuArq zE-dY)1@aCLvSVA3IF0xzOGR5naREcaA|@94ye5`1raLEE3n?~@k8VT%ft|mNq0m^V zU-;41uX9rYU*~Ifi#MCbT>`S{4Gw?uP;R45ybI4oh+Y!p{B&Q7VUWh0`PRr8W94JK z@~8=nxLn&vul&24ZAR?3I7-f^>2X;PesiR%=OiKc#oB3JpSEN0?p}P8&vMRE2y1!S zLqmwGuO4H2HzqfsN%6eVHa~54@iLAsOzWhHRHaN6+|^%@ZRq|c6{>!gMHxQdj- zW+HD9EQ$J%<4JN{*e_(wDZLxo`9wA{Kl8puhE(UH|rd z0*`F{bZW;dvNpnLDL>Zp>*}dISRn;IS~*(U%hb@QvpI%S^~5~RSqnK;gXVD26HQA# z*JzBipnpD<*Zv)?aUd(|anKFQ@X8sl@JAY7K6wRhD*YC?Q&z^(L2?@Quyp2;eS$&u8DZKIr1T+{HyDo*!l$Y zi}(e*`%6U?3OWyHw(+x>=4&iW#$t@#5B6D?<>y%-WcXP-lZHzb1cGHMTa?WQ(nDpg z9-H9%$hNX)cPYFw_1XLcfF_>^bPQFm18Mbqd0|N@9ek0M58PeZWYJeRFdS{ z&v37uqKe^owP5CnljcfT#pDxaECu#L_ADCGl>FzmY-+3Kc>4!l*58}{n`J;D^Ll1f z&uAr4!l8qi69UJ-j>x8G7!y|}v1teJzUPX*MQ92XvWkzg2Oz(-&UV>ee}9dqG%J2{ zEI)ha$eww#u)ZwOq0Vb6*A^(h7U20mSq}M*681tDUsojE*x$DTr%~wM!fx& zKs1`#^$CFq@A>w+RUBJ>mx*8W7nQ_IXN&WPd=p)l!q48n)!xTZql5qQL2w(*iO^iS z1GCx}e4-SF--!ki=|0VP)y*lC->9d%=t?`%$`Z$*T2Gn;Ph`DLlg*|){mwNj^di&49bg{O6t?_^jFw++A{?v=W}0Rk>PkXnKwc#oa$ay_gpx-pk6VR*>$hc_AOI{{etLJ z@cEtkhhN$rdt~GO#N`;rr;_sO%LQ*E2D%SpE>KMs^GtrDF7}p*_=BW>>(gPt`P6zz zar$*$%}9oE95vT;)=~=gwD;Baf!mAg2=d3QuT`UAW6@;=ML zuS^Sx!(+Vte6@y8QiHb9cHEOKNHEh*4XU9ILojH^+>D%Cq#YC6l8EtH)*JeUR4h+@no>ycyVId?xd}{bH&vT zJJH#?1-fk!9Pdu*vd2V@hB4Xm&j?dm2Yu?dHZ?_*Y~_BU5lv%2^~lwo6^T`?{1Cq5 znQ047URS;UPMhNG*gH#j>2!ofz)|X4meX9{nR@zLE0UCVv(JWHYdk67dVFiH?xX+< zKtZT3PNf^{6EcqdxJiwVC#1v_UC(u<-#Mylh5K;-9@rM+gS&FnJcYtFq~~n&VUG>2 zJ-+?r#qb=BjZNU67QDZ857DR%L7-mUR%H||aIWb`x`QXBdO8X^zPs(tyr_g%VolCC z(3Tu6)1Gu$RCnh-E$is|=(p~+c)>lYh_mH_iw|HkAu;dR7hm?JRw-l8ITAwYF?&jO z?0l?+&+y#CR(s(^6Xr9c8;Q~+nzzCn{@|kJ)9Y|z3-dOHJLznv_!%^{x2#+tE*iY} zD97WGcQTnYUAFvozN1H?UPmrLrM6)?*2Sw(2BzYv<~$oqvTCkuRle9qg_EOnxwfh7 zRp7FeqdJNE_yk+bFt&h4dF4q>%Q$6ptik*r?DTJ)EpXno-b_{F>Yx*1m7qdPs!$>O z9Fdf&V>{rQFFbW?gKA`0(T1j;G%Q_M zq}ikE>+2=g)xrHIzW&Aku;>?7~riyzLClz+1#xQQGFM-q}+_mD}I~wb?5WVNb2ixKJOVc!%8;YdA;XS$Zd+< z@rMonFqwbrYGDb#=nR9eUiF-5lGLIUQqROF#qx3O-*m6@?FqVf#}95%*q$d%QzjHG z#<=PJ7^Bc12L5Xg3Y<=^pDo})K_8ilx3MA}YdP(Qik63dE5%&Pn$;egB%-eh8kX!5 z<}ZBl)Nvjez?7pcXd?bh==$01#2uW9ny55?9aL%ljokF;-tn5Ek{TcTl*djT?ajyL z98EE22v2K|E#=5o7mt}=xJsWKqHs+*OG6J8a@9I4KhyUZf9AF~`?%H9MFqU9 z-C+}p+?(ugnbzDNrhZ8w74W;1*uV9iFyIVry_6CLgoNEFhK_HrP|Ho@voqPe2YSD( zkTi^`sY_ftWJiciDuSWni39pBLr>N0FWjBJTG|=;asNQ8%t@D4Rg1RNyACSiBdB|_ z_fC8qSmNegzTDYXMROm~zsPMeQB2pNbpI5lx@k{B)1KA}%W?jaAb-P)O~t#P4WC-s z*X+%8g7cPuVM880;ge3?9V1%f;-)Rb%Wx3L?NxF% zJ)Vd3yB{E#fOfM}aj|j;zj(j-)4OM<3#bl{-M70ay?Hr(&s|E*j84})`1jWLe3#HH zg=OzGg>UF{_Sa;g(kZe+=^VIDt5yE2S5(-L^h=Y%`LVE=V z3YtbtcP$E5DD68vnbB#`yvSL_-Xn2Uy=UtU2^f_=o7@swn1jE!r*}-o-|E~x%Bw6o zqMZITXE$xRI(XDSStq=4?+)~mYfM0Qg|>)7muJt{xGHH^?u9^3Gap1|37(k?4QoWade zur4qmvhhJ?Re{z0r`b>EzSF3h2j%}^7S_9<|K`er6a4j)fWhNUk(-nbYY9->zz1Hm z8t^qIcC_|Vb&{7J&x6~-jo*55D>$X)@swdVy)I$A@`thi+NlJ`=<5epJ>9`b#mAuh z(P)r$mU~}ubYJ$f?^nl>8H!3viu`+LkhGWQX7LZ2ryu4uNqxunmD;3;@2U+nFkyb5 z7+pWhq349uzZZG%z)oeW?zHySRP>Dt(?i5XxREFpP)54#SW8c4dxI7l%&0 zj!HfXQ?53N%}C%(aay+HGnP0jd3#dBEoR5;VjC=mEy+~yc>%*2y=B=*quUN0^|zj6 zZiQ>5z|NjcY7wOW&T#IPB+sagi~MN;Ke<3l`A>|PwSEDc|*?#Ou7hKWsiHKA1gOV&8kqmCTNI#wo25bvYbSIl^G=?>K zK13w+sFqNz$QgMi#@u5^dGq5kw|G!^Kg_uvOUX6UZ*`T&GV)P##z=_59=1Ts&nr)t z0=|Exi>|#MT8zu9?H;wE&$HI_Cf&j~`bmo(#@3r#pV)1?cs}KR zT!er&pTYjz4?@Kl#YC$7QvLjRp61Z^9RgWa#sba^Uo5l+o_e!&Z^!QCER`h`sGDYX zv^CR<(R{1#YE(7aUMkDN>Un!W`CI11h}5e`H>;ZGmyUQ>)+0I0X5L-fk*IxbNeVHv zBsV<1{FSn(z?}0B3jAAF6Akdl>lKL8>tF;cb)5r@vxt3jm~FO6gU^bK+k?GUTUV6K zT9au5irczH-)rrYIlz2f@^%G3{S_a zO_uye4j!KRf07C=t z1$YBG_J$xBhhe{CF97V|C-!0$Sn*$-Tx`Hz{D7oGc!K{P_F~1MR^jNtEZ3k$ z>s{XeC(H!~y%BTq=aU*B*hb6+!1k}lS^!x6PpkzN{hwhi)?$YL#afW>>i-vO@n2#s zfTjJXIKjWBLTk9e*-Z}>sU4vvOAR;WaVnUODJp(pZ|f&PKbAa5^dGCTve zy5j(N4Y`#gz^AO1oZ#fE3DDLJplw!Z?f?z+qXg|m02xAVdptOg8WDXn4{H_H$dO~D1ogG`(qzn-5`NclWUW}?~;C$$U7wV$Dq)r39jGC zb;x@u*khrGpF6@YVF(IN-qV3NYG^pv41cW(J+G-%5w-e*Dn&qB+b93|Nf^S$3Qi7M z5Q^xvYGCVKh0^`}<=DDvn6+w1N$EdVgkAvf<4?xdIkrEE>zuWp#9t2OP!j9#i*8Qt zKHhL}?(wUj>%&524c!DXy_CDr9TuJ3s4*zY3Sc+C~0ugxS<{f2YtZ5^oPX#u2Uoq`@0TsQUD9Lp)DQ> zEndI&hsT1;wv9AAv@&g|NBE6DBpBki{-iMA?sG$1DJ;O;ZKO#5*;38 literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binary-8.949963.png b/examples/phase/generated/binary/binary-8.949963.png new file mode 100644 index 0000000000000000000000000000000000000000..0f4fa8b1c4ee1f6385c1e0aa4c8a69d824f9edd1 GIT binary patch literal 21173 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 literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binaryCoupled-0.000899.pdf b/examples/phase/generated/binary/binaryCoupled-0.000899.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6bd3fd49d071f94e68b73194da45d5c90fc260dd GIT binary patch literal 14655 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 E10-F;n*aa+ literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binaryCoupled-0.000899.png b/examples/phase/generated/binary/binaryCoupled-0.000899.png new file mode 100644 index 0000000000000000000000000000000000000000..c74fd2ab538b5103fe4ce7e8acb5663b88aeb022 GIT binary patch literal 20140 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 ZIcj0_8nI#A@RmfB`UNdak&?xo{|jhM4+{VQ literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binaryCoupled-8.949963.pdf b/examples/phase/generated/binary/binaryCoupled-8.949963.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6835e184c01125552eed9062af731a2e236b7d3f GIT binary patch literal 15373 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 W2}Ba*^G9JZ7z|8IOvgkQ_J07Rq9P^$ literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/binaryCoupled-8.949963.png b/examples/phase/generated/binary/binaryCoupled-8.949963.png new file mode 100644 index 0000000000000000000000000000000000000000..80bb0f69a70fae5cc363227e448bc3c1ae7bfbcb GIT binary patch literal 21133 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 literal 0 HcmV?d00001 diff --git a/examples/phase/generated/binary/moving.pdf b/examples/phase/generated/binary/moving.pdf deleted file mode 100644 index 422f7f6232b7392efb02e604868db5785978a629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20847 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 PT0!`Yv9YVS+xq_ik%-h( diff --git a/examples/phase/generated/binary/moving.png b/examples/phase/generated/binary/moving.png deleted file mode 100644 index c1f11a33b7d2286cf1e3951dddd2290c487018b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37747 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�QEjGMy2^aInGgVC-*|cv)%!t$BzY3n z(!A$a$RIGuL-iRR)hbqHGkF>5R$cx(A%w1UNzuUdEX~P5^>b0iKbNYHDmA82O>Fd= zw`o5B!Sr(WsTPB%U`0fyYI)E$Nv~wfHxrHzsSn2{j}3>IRcE|EVmoAZO_W&jxZw08 z#H_R2qV9iiaHX{oMqGNevPN#Ra9wdQ+!)Vw3$LZ5$CYi8?LzvC+y=f}F#E>=-#-9OGR5gcm8?3QAEFh>5QwhQ`B=j6CNea*Obq&_(xZ!D4q? zeM*4Xf&PsBGbbiC4*o50w9?R{-&I6hp~|06+(vt$F;!Dr-TamoeU?J5t(=o|ta`(l zaS;AbD+hZ4&Q#9j$-B^2AszS9hgiiWaLJ)EzC25AlZm_vRaE!pO|P_`za-tGYaHjqw((b6`pYuFO{*T{8uX6dnY z&s4v>-b_7Vk1{)WHp>NGEw8$Eqkn^%*N!T~o1isD7Kjcq&xaABjhThiD`Qf~R*nt~ z+4C0LB_hLWLAR6xKyKcp3LT=mwLx?;s~cnR;~V5#J#urBp+Z#|L5pEEA&NTrOo#T> ziG|wlbU0rv>Xx&Xc#~jYb-uJjxV2pU&;(hftNDqy$QLL_w52{feO!JZpXU@gz=yeK zCe5v)lwqGTL<_KnEd<_jDnC)+GkNc^RHO-!U>Ns~j$8KV%BLzN4$f3mxpYR>bv|*a z-si{u*fDNS)AAD{c;!pfu?+i6vLnD%$nqx3N~8Bm7E(rk>^Rb62*03F+k@j@WSv*n5=7$KvNN2fopj z&ynZVGNB4kv(O2H6S7cZ{+redb7~i2-X--Z#T3)U3PBEsSyki5d7Uj#c)ol235T0u z(Do)0g`|Kvcfgz}ZjfqN8d z{q=Wga(=y{Qt4A;c1F6_@A=fJZjcqr&l*MgECikvRGxmaxnhgKdM^LGj{RG&H6Of3 zcD0!hu0R<(Yl}z;Np#c2PdulhZ&!86`aKM+qrc7`0jClax1IC|a4N3*X> z8#*zFF})Zp-%r~wr@!pV%bLF6eel{6+pSRYOVyoa?%#_GA5PC?>{6ya{4jauU7Z7K zoZK1CFvG2VJ<1FJBs^d{eL?ea!9HJ#*vCb z1IaeJ$ZND5d)e2|suyZSYm6jHVH4CZea(F5-W|_8&tVViZ&iz09W?k~{+eGp9VAtQ zDMq_-7@1=J_1hUR6^XofyGrrlzXMSt5#d>$fBd#8-tU*zx4|4tXupH+e*d-;9Eo=w zMKQYU@9)ophIC#%`B%|V%A5Zg-hWn)@E_Xy&(XN^KaH{c*v!Iu)wQL44gVVWr>=VP KNSexp>;DT_Tv;9f diff --git a/examples/phase/generated/binary/stationary.pdf b/examples/phase/generated/binary/stationary.pdf index 91cce042d81a3872c5425879880a06d207b663db..b93bbd800aff1967babd02a6ebb63b7c72569144 100644 GIT binary patch literal 13940 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 diff --git a/examples/phase/generated/binary/stationary.png b/examples/phase/generated/binary/stationary.png index 099453ac24888fed8d24bd3daad4e6edcc54924b..9c8e29d0bc8956b40b6e9ad95b6e9a8100c09dd8 100644 GIT binary patch literal 18446 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 bFAd+Rs!P0`I>Nufzav`54rLuY9q|7Eh3Og6 diff --git a/examples/phase/index.rst b/examples/phase/index.rst index e6bae7acae..ea9d83ada4 100644 --- a/examples/phase/index.rst +++ b/examples/phase/index.rst @@ -7,6 +7,7 @@ Phase Field Examples :template: example.rst examples.phase.simple + examples.phase.binary examples.phase.binaryCoupled examples.phase.quaternary examples.phase.anisotropy From b465d7e5283127f45a8b05e69f36a2370fe95256 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 08:44:12 -0500 Subject: [PATCH 012/175] Revise description of solidification evolution --- examples/phase/binaryCoupled.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index a8fb83e1a6..07b4dac190 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -754,25 +754,28 @@ def deltaChemPot(phase, C, T): :width: 30% :alt: phase and composition fields at t=1080000, compared with final phase diagram concentrations -The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in -:math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid +The interface moves :math:`\\approx \\unit{2.8}{\\micro\\meter}` in +:math:`\\unit{70}{\\milli\\second}`, driven by diffusion in the liquid phase (compare the estimate above of \\unit{0.1}{\\second}}). For the next -:math:`\\unit{20}{\\second}`, the interface stalls while the solute step +:math:`\\unit{12}{\\second}`, the interface stalls while the solute step trapped in the solid phase diffuses outward -(:math:`(\\unis{3.4}{\\micro\\meter})^2 / D_s = -\mathcal{O}(\\unit{100}{\\second})`). Once the solute gradient in the +(:math:`(\\unit{2.8}{\\micro\\meter})^2 / D_s = +\mathcal{O}(\\unit{80}{\\second})`). Once the solute gradient in the solid reaches the new position of the interface, the solidification front begins to move, driven by diffusion in the solid. When the solute in the solid becomes uniform, the interface stalls again after :math:`\\approx \\unit{4000}{\\second}`, having moved another -:math:`\\unit{3.2}{\\micro\\meter}` (recall the estimate of +:math:`\\unit{2.9}{\\micro\\meter}` (recall the estimate of :math:`\\unit{1000}{\\second}` for equilibration in the solid). After this point, there is essentially no further motion of the interface and barely -perceptable changes in the concentration field. The fact that the -interface does not reach the predicted phase fraction is due to the fact -that this phase field model accounts for adsorption at the interface, -resulting in the bulk phases not having exactly the concentrations assumed -in the sharp interface treatment. +perceptable changes in the concentration field. + +.. note:: + + This evolution is qualitatively consistent with that seen in + :mod:`examples.phase.binary`, but the interface does not move as far and + the bulk concentrations are further from the phase diagram values. The + computation also takes substantially longer than the uncoupled variant. .. rubric:: Footnotes From cd469d6af24a467360b4b45d7ae21204d9b63fa2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 09:20:07 -0500 Subject: [PATCH 013/175] Deprecate fipy.steppers Can't deprecate base class for some reason. Don't really need to. --- documentation/glossary.rst | 5 +++++ fipy/__init__.py | 2 -- fipy/steppers/__init__.py | 17 +++++++++++++++++ fipy/steppers/pidStepper.py | 3 +++ fipy/steppers/pseudoRKQSStepper.py | 3 +++ fipy/steppers/stepper.py | 4 ++++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/documentation/glossary.rst b/documentation/glossary.rst index b9abaee4d6..f2839f5b31 100644 --- a/documentation/glossary.rst +++ b/documentation/glossary.rst @@ -186,6 +186,11 @@ Glossary See http://sphinx.pocoo.org/. + steppyngstounes + This package provides iterators that simplify both deterministic and + adaptive time (or other independent variable) stepping. + See https://github.com/guyer/steppyngstounes. + TravisCI A cloud-based :term:`Continuous Integration` tool. See https://travis-ci.org. diff --git a/fipy/__init__.py b/fipy/__init__.py index 0d328c18d3..1d73bd6dab 100644 --- a/fipy/__init__.py +++ b/fipy/__init__.py @@ -40,7 +40,6 @@ from fipy.boundaryConditions import * from fipy.meshes import * from fipy.solvers import * -from fipy.steppers import * from fipy.terms import * from fipy.tools import * from fipy.variables import * @@ -50,7 +49,6 @@ __all__.extend(boundaryConditions.__all__) __all__.extend(meshes.__all__) __all__.extend(solvers.__all__) -__all__.extend(steppers.__all__) __all__.extend(terms.__all__) __all__.extend(tools.__all__) __all__.extend(variables.__all__) diff --git a/fipy/steppers/__init__.py b/fipy/steppers/__init__.py index 360029815f..701f59dd42 100644 --- a/fipy/steppers/__init__.py +++ b/fipy/steppers/__init__.py @@ -5,11 +5,14 @@ from fipy.steppers.stepper import Stepper from fipy.steppers.pseudoRKQSStepper import PseudoRKQSStepper from fipy.steppers.pidStepper import PIDStepper +from fipy.tools.decorators import deprecate __all__ = ["L1error", "L2error", "LINFerror", "sweepMonotonic"] from future.utils import text_to_native_str __all__ = [text_to_native_str(n) for n in __all__] +@deprecate(version="3.4.3", + message="Pass a ``residualFn`` to :meth:`~fipy.terms.term.Term.sweep`.") def residual(var, matrix, RHSvector): r""" Determines the residual for the current solution matrix and variable. @@ -34,6 +37,9 @@ def residual(var, matrix, RHSvector): Lx = matrix * array(var) return LINFnorm(Lx - RHSvector) +@deprecate(version="3.4.3", + message="Calculate error explicitly with " + ":mod:`~fipy.tools.numerix`.") def error(var, matrix, RHSvector, norm): r""" .. math:: @@ -60,6 +66,9 @@ def error(var, matrix, RHSvector, norm): denom = L1norm(var.old) return L1norm(var - var.old) / (denom + (denom == 0)) +@deprecate(version="3.4.3", + message="Calculate error explicitly with " + ":mod:`~fipy.tools.numerix.L1norm`.") def L1error(var, matrix, RHSvector): r""" .. math:: @@ -81,6 +90,9 @@ def L1error(var, matrix, RHSvector): from fipy.tools.numerix import L1norm return error(var, matrix, RHSvector, L1norm) +@deprecate(version="3.4.3", + message="Calculate error explicitly with " + ":mod:`~fipy.tools.numerix.L2norm`.") def L2error(var, matrix, RHSvector): r""" .. math:: @@ -102,6 +114,9 @@ def L2error(var, matrix, RHSvector): from fipy.tools.numerix import L2norm return error(var, matrix, RHSvector, L2norm) +@deprecate(version="3.4.3", + message="Calculate error explicitly with " + ":mod:`~fipy.tools.numerix.LINFnorm`.") def LINFerror(var, matrix, RHSvector): r""" .. math:: @@ -123,6 +138,8 @@ def LINFerror(var, matrix, RHSvector): from fipy.tools.numerix import LINFnorm return error(var, matrix, RHSvector, LINFnorm) +@deprecate(version="3.4.3", + message="Use the :term:`steppyngstounes` package instead.") def sweepMonotonic(fn, *args, **kwargs): """ Repeatedly calls :func:`fn(*args, **kwargs)` until the residual returned by diff --git a/fipy/steppers/pidStepper.py b/fipy/steppers/pidStepper.py index 6de962f224..3b1ec30bb2 100644 --- a/fipy/steppers/pidStepper.py +++ b/fipy/steppers/pidStepper.py @@ -1,11 +1,14 @@ from __future__ import division from __future__ import unicode_literals from fipy.steppers.stepper import Stepper +from fipy.tools.decorators import deprecate __all__ = ["PIDStepper"] from future.utils import text_to_native_str __all__ = [text_to_native_str(n) for n in __all__] +@deprecate(version="3.4.3", + message="Use the :term:`steppyngstounes` package instead.") class PIDStepper(Stepper): """ Adaptive stepper using a PID controller, based on:: diff --git a/fipy/steppers/pseudoRKQSStepper.py b/fipy/steppers/pseudoRKQSStepper.py index 20a9dd6694..8ba0d764e7 100644 --- a/fipy/steppers/pseudoRKQSStepper.py +++ b/fipy/steppers/pseudoRKQSStepper.py @@ -1,10 +1,13 @@ from __future__ import unicode_literals from fipy.steppers.stepper import Stepper +from fipy.tools.decorators import deprecate __all__ = ["PseudoRKQSStepper"] from future.utils import text_to_native_str __all__ = [text_to_native_str(n) for n in __all__] +@deprecate(version="3.4.3", + message="Use the :term:`steppyngstounes` package instead.") class PseudoRKQSStepper(Stepper): """ Adaptive stepper based on the ``rkqs`` (Runge-Kutta diff --git a/fipy/steppers/stepper.py b/fipy/steppers/stepper.py index dce9b3c062..4cdd2e2544 100644 --- a/fipy/steppers/stepper.py +++ b/fipy/steppers/stepper.py @@ -2,10 +2,14 @@ from builtins import object __docformat__ = 'restructuredtext' +# from fipy.tools.decorators import deprecate + __all__ = ["Stepper"] from future.utils import text_to_native_str __all__ = [text_to_native_str(n) for n in __all__] +# @deprecate(version="3.4.3", +# message="Use the :term:`steppyngstounes` package instead.") class Stepper(object): def __init__(self, vardata=()): self.vardata = vardata From e1ff04a47acabc5a8d9444a7f2c48f930427ffd0 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 09:29:16 -0500 Subject: [PATCH 014/175] Add discussion of adaptive stepping to USAGE --- documentation/USAGE.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/documentation/USAGE.rst b/documentation/USAGE.rst index 553c03ec6b..f27fc15207 100644 --- a/documentation/USAGE.rst +++ b/documentation/USAGE.rst @@ -937,6 +937,19 @@ Nothing different needs to be done when % \subsection{Internal boundary conditions} +----------------- +Adaptive Stepping +----------------- + +Step size can be controlled with the :term:`steppyngstounes` package. +Demonstrations of its use are found in :mod:`examples.phase.binary` and +:mod:`examples.phase.binaryCoupled.` + +.. note:: + + The old :mod:`fipy.steppers` classes are now deprecated. They were + undocumented and did not work very well. + .. _RunningUnderPython2: ---------------------- From 8e185630244bfae4b65d068d79f27f546b441972 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 10:50:41 -0500 Subject: [PATCH 015/175] Fix spelling errors --- examples/phase/binary.py | 12 ++++++------ examples/phase/binaryCoupled.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 7f5103373a..9addc8a946 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -652,7 +652,7 @@ def deltaChemPot(phase, C, T): could again verify the final concentrations and phase fraction against the expected values. -We can estimate the time to equlibration by examining the time for the +We can estimate the time to equilibration by examining the time for the diffusion field to become uniform. In the liquid, this will take :math:`\\mathcal{O}((\\unit{10}{\\micro\\meter})^2 / D_l) = \\unit{0.1}{\\second}` and in the solid @@ -660,10 +660,10 @@ def deltaChemPot(phase, C, T): \\unit{1000}{\\second}`. Not wanting to take a hundred-million steps, we employ adaptive time -stepping, using the steppyingstounes package. This package takes care of -many of the messy details of stepping, like overshoot, underflow, and step -size adaptation, while keeping the structure of our solve loop largely -intact. +stepping, using the :term:`steppyingstounes` package. This package takes +care of many of the messy details of stepping, like overshoot, underflow, +and step size adaptation, while keeping the structure of our solve loop +largely intact. >>> from steppyngstounes import SequenceStepper, PIDStepper >>> from itertools import count @@ -744,7 +744,7 @@ def deltaChemPot(phase, C, T): :math:`\\unit{3.2}{\\micro\\meter}` (recall the estimate of :math:`\\unit{1000}{\\second}` for equilibration in the solid). After this point, there is essentially no further motion of the interface and barely -perceptable changes in the concentration field. The fact that the +perceptible changes in the concentration field. The fact that the interface does not reach the predicted phase fraction is due to the fact that this phase field model accounts for adsorption at the interface, resulting in the bulk phases not having exactly the concentrations assumed diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index 07b4dac190..baf53bacbc 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -678,7 +678,7 @@ def deltaChemPot(phase, C, T): could again verify the final concentrations and phase fraction against the expected values. -We can estimate the time to equlibration by examining the time for the +We can estimate the time to equilibration by examining the time for the diffusion field to become uniform. In the liquid, this will take :math:`\\mathcal{O}((\\unit{10}{\\micro\\meter})^2 / D_l) = \\unit{0.1}{\\second}` and in the solid @@ -686,10 +686,10 @@ def deltaChemPot(phase, C, T): \\unit{1000}{\\second}`. Not wanting to take a hundred-million steps, we employ adaptive time -stepping, using the steppyingstounes package. This package takes care of -many of the messy details of stepping, like overshoot, underflow, and step -size adaptation, while keeping the structure of our solve loop largely -intact. +stepping, using the :term:`steppyingstounes` package. This package takes +care of many of the messy details of stepping, like overshoot, underflow, +and step size adaptation, while keeping the structure of our solve loop +largely intact. >>> from steppyngstounes import SequenceStepper, PIDStepper >>> from itertools import count @@ -768,7 +768,7 @@ def deltaChemPot(phase, C, T): :math:`\\unit{2.9}{\\micro\\meter}` (recall the estimate of :math:`\\unit{1000}{\\second}` for equilibration in the solid). After this point, there is essentially no further motion of the interface and barely -perceptable changes in the concentration field. +perceptible changes in the concentration field. .. note:: From 272e249717fed586fe91a5dda207281b9194f607 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 11:00:03 -0500 Subject: [PATCH 016/175] Install steppyngstounes on CIs --- .appveyor.yml | 1 + .circleci/config.yml | 1 + .travis.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index 4449b28bfe..d42d80e56e 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -93,6 +93,7 @@ install: - cmd: if "%TARGET_ARCH%" == "x86" if "%FIPY_SOLVERS%" == "pysparse" conda.exe install --quiet --name root pysparse - cmd: pip install scikit-fmm + - cmd: pip install git+https://github.com/guyer/steppyngstounes.git # Skip .NET project specific build phase. build: off diff --git a/.circleci/config.yml b/.circleci/config.yml index c02914de20..550fe66909 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,6 +40,7 @@ commands: source activate ~/project/<< parameters.condaenv >> conda remove --quiet --channel conda-forge --force fipy pip install scikit-fmm + pip install git+https://github.com/guyer/steppyngstounes.git test_fipy: description: "Run FiPy Tests" diff --git a/.travis.yml b/.travis.yml index 2d246a3007..6609c90f25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,6 +54,7 @@ before_install: # Useful for debugging any issues with conda - conda info -a - pip install scikit-fmm + - pip install git+https://github.com/guyer/steppyngstounes.git install: - python setup.py install before_script: From f72d1f8fc36cb33a1c439a7e577add2c2daee882 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 11:14:44 -0500 Subject: [PATCH 017/175] Discard result of succeeded() --- examples/phase/binary.py | 2 +- examples/phase/binaryCoupled.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 9addc8a946..7d4bdf2979 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -710,7 +710,7 @@ def deltaChemPot(phase, C, T): ... # the last step might have been smaller than possible, ... # if it was near the end of the checkpoint range ... dt = step.want -... checkpoint.succeeded() +... _ = checkpoint.succeeded() ... if __name__ == '__main__': ... viewer.plot() diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index baf53bacbc..0c33fd72ff 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -734,7 +734,7 @@ def deltaChemPot(phase, C, T): ... # the last step might have been smaller than possible, ... # if it was near the end of the checkpoint range ... dt = step.want -... checkpoint.succeeded() +... _ = checkpoint.succeeded() ... if __name__ == '__main__': ... viewer.plot() From 1ca252d6f0c1dd7f6dfe44251b0c1a31c9231f7f Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 11:24:46 -0500 Subject: [PATCH 018/175] Fix typo --- examples/phase/binary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 7d4bdf2979..d9d35fea24 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -735,7 +735,7 @@ def deltaChemPot(phase, C, T): phase (compare the estimate above of \\unit{0.1}{\\second}}). For the next :math:`\\unit{20}{\\second}`, the interface stalls while the solute step trapped in the solid phase diffuses outward -(:math:`(\\unis{3.4}{\\micro\\meter})^2 / D_s = +(:math:`(\\unit{3.4}{\\micro\\meter})^2 / D_s = \mathcal{O}(\\unit{100}{\\second})`). Once the solute gradient in the solid reaches the new position of the interface, the solidification front begins to move, driven by diffusion in the solid. When the solute in the From 1f5a3c523bddc9992c3f207567e298d6458e79f2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 28 Jan 2021 13:22:16 -0500 Subject: [PATCH 019/175] Fix math --- examples/phase/binary.py | 3 ++- examples/phase/binaryCoupled.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index d9d35fea24..7becea1ff9 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -732,7 +732,8 @@ def deltaChemPot(phase, C, T): The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in :math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid -phase (compare the estimate above of \\unit{0.1}{\\second}}). For the next +phase (compare the estimate above of :math:`\\unit{0.1}{\\second}}`). +For the next :math:`\\unit{20}{\\second}`, the interface stalls while the solute step trapped in the solid phase diffuses outward (:math:`(\\unit{3.4}{\\micro\\meter})^2 / D_s = diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index 0c33fd72ff..243f9aeebf 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -756,7 +756,8 @@ def deltaChemPot(phase, C, T): The interface moves :math:`\\approx \\unit{2.8}{\\micro\\meter}` in :math:`\\unit{70}{\\milli\\second}`, driven by diffusion in the liquid -phase (compare the estimate above of \\unit{0.1}{\\second}}). For the next +phase (compare the estimate above of :math:`\\unit{0.1}{\\second}}`). +For the next :math:`\\unit{12}{\\second}`, the interface stalls while the solute step trapped in the solid phase diffuses outward (:math:`(\\unit{2.8}{\\micro\\meter})^2 / D_s = From 5682e258504e6b33583804f0ca2a48523361634a Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 2 Feb 2021 22:20:14 -0500 Subject: [PATCH 020/175] Ensure mass conservation of early evolution --- examples/phase/binary.py | 4 ++-- examples/phase/binaryCoupled.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 7becea1ff9..63a871f15f 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -554,7 +554,7 @@ def deltaChemPot(phase, C, T): >>> C.updateOld() >>> phaseRes = 1e+10 >>> diffRes = 1e+10 ->>> while phaseRes > 1e-3 or diffRes > 1e-3: +>>> while phaseRes > 1e-3 or diffRes > 1e-3 or abs(Cavg.value - 0.5) > 5e-7: ... phaseRes = phaseEq.sweep(var=phase, dt=dt) ... diffRes = diffusionEq.sweep(var=C, dt=dt, solver=solver) >>> from fipy import input @@ -635,7 +635,7 @@ def deltaChemPot(phase, C, T): ... C.updateOld() ... phaseRes = 1e+10 ... diffRes = 1e+10 -... while phaseRes > 1e-3 or diffRes > 1e-3: +... while phaseRes > 1e-3 or diffRes > 1e-3 or abs(Cavg.value - 0.5) > 1e-6: ... phaseRes = phaseEq.sweep(var=phase, dt=dt0) ... diffRes = diffusionEq.sweep(var=C, dt=dt0, solver=solver) ... elapsed.value = (i + 1) * dt0 diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index 243f9aeebf..a1c765b314 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -661,7 +661,7 @@ def deltaChemPot(phase, C, T): ... C.updateOld() ... res = 1e+10 ... sweep = 0 -... while res > 1e-3 and sweep < 20: +... while (res > 1e-3 or abs(Cavg.value - 0.5) > 1e-8) and sweep < 20: ... res = eq.sweep(dt=dt0, solver=solver) ... sweep += 1 ... elapsed.value = (i + 1) * dt0 From 4fe044bac01a5ba4509d126c66281a8ebcf87eac Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 3 Feb 2021 10:30:45 -0500 Subject: [PATCH 021/175] Fix LaTeX --- examples/phase/binaryCoupled.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/phase/binaryCoupled.py b/examples/phase/binaryCoupled.py index a1c765b314..895ecbc207 100755 --- a/examples/phase/binaryCoupled.py +++ b/examples/phase/binaryCoupled.py @@ -756,7 +756,7 @@ def deltaChemPot(phase, C, T): The interface moves :math:`\\approx \\unit{2.8}{\\micro\\meter}` in :math:`\\unit{70}{\\milli\\second}`, driven by diffusion in the liquid -phase (compare the estimate above of :math:`\\unit{0.1}{\\second}}`). +phase (compare the estimate above of :math:`\\unit{0.1}{\\second}`). For the next :math:`\\unit{12}{\\second}`, the interface stalls while the solute step trapped in the solid phase diffuses outward From e6842e9da8f60b0e8ea144bc97b40adf1be1552d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 3 Feb 2021 12:33:55 -0500 Subject: [PATCH 022/175] Fix LaTeX --- examples/phase/binary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/phase/binary.py b/examples/phase/binary.py index 63a871f15f..2b8f0456c9 100755 --- a/examples/phase/binary.py +++ b/examples/phase/binary.py @@ -732,7 +732,7 @@ def deltaChemPot(phase, C, T): The interface moves :math:`\\approx \\unit{3.4}{\\micro\\meter}` in :math:`\\unit{80}{\\milli\\second}`, driven by diffusion in the liquid -phase (compare the estimate above of :math:`\\unit{0.1}{\\second}}`). +phase (compare the estimate above of :math:`\\unit{0.1}{\\second}`). For the next :math:`\\unit{20}{\\second}`, the interface stalls while the solute step trapped in the solid phase diffuses outward From 7e8a4b9a453423667bcc95164ef316cb3da29a2d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 08:30:13 -0400 Subject: [PATCH 023/175] Set up CI with Azure Pipelines [skip ci] --- .azure/pipelines.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .azure/pipelines.yml diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml new file mode 100644 index 0000000000..5bf2ede17f --- /dev/null +++ b/.azure/pipelines.yml @@ -0,0 +1,38 @@ +# Conda package +# Create and test a Python package on multiple Python versions. +# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: +# https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/anaconda + +jobs: +- job: + displayName: ubuntu-16.04 + pool: + vmImage: 'ubuntu-16.04' + strategy: + matrix: + Python27: + python.version: '2.7' + Python36: + python.version: '3.6' + + steps: + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH + + - bash: conda create --yes --quiet --name myEnvironment + displayName: Create Anaconda environment + + - bash: | + source activate myEnvironment + conda install -v --yes --quiet --name myEnvironment --show-channel-urls --channel conda-forge python=$PYTHON_VERSION numpy + conda remove --quiet --channel conda-forge --force fipy + displayName: Install Anaconda packages + - bash: | + source activate myEnvironment + pip install scikit-fmm + displayName: Install pip packages + - bash: | + source activate myEnvironment + python setup.py egg_info + python setup.py test --deprecation-errors + displayName: test From e8c0afdf429cfe91f8db1156ffe5f8554fd5b2a6 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 08:38:25 -0400 Subject: [PATCH 024/175] Update pipelines.yml for Azure Pipelines --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 5bf2ede17f..666c40f84a 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,7 +24,7 @@ jobs: - bash: | source activate myEnvironment - conda install -v --yes --quiet --name myEnvironment --show-channel-urls --channel conda-forge python=$PYTHON_VERSION numpy + conda install -v --yes --quiet --name myEnvironment --show-channel-urls --channel conda-forge python=$PYTHON_VERSION fipy pytrilinos gmsh conda remove --quiet --channel conda-forge --force fipy displayName: Install Anaconda packages - bash: | From 84092c5eafd459c30a85443da39cd040740d45af Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 10:01:12 -0400 Subject: [PATCH 025/175] Switch to mamba --- .azure/pipelines.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 666c40f84a..9e51b814a9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -19,13 +19,13 @@ jobs: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH - - bash: conda create --yes --quiet --name myEnvironment + - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment - bash: | source activate myEnvironment - conda install -v --yes --quiet --name myEnvironment --show-channel-urls --channel conda-forge python=$PYTHON_VERSION fipy pytrilinos gmsh - conda remove --quiet --channel conda-forge --force fipy + mamba install -v --yes --quiet --name myEnvironment --show-channel-urls --channel conda-forge python=$PYTHON_VERSION fipy pytrilinos gmsh + mamba remove --quiet --channel conda-forge --force fipy displayName: Install Anaconda packages - bash: | source activate myEnvironment From cc9d749c262f7c813c60862397aab1acf05a1c4d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 10:39:53 -0400 Subject: [PATCH 026/175] Fix mamba install options --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 9e51b814a9..3ef717339e 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,7 +24,7 @@ jobs: - bash: | source activate myEnvironment - mamba install -v --yes --quiet --name myEnvironment --show-channel-urls --channel conda-forge python=$PYTHON_VERSION fipy pytrilinos gmsh + mamba install --channel conda-forge python=$PYTHON_VERSION fipy pytrilinos gmsh mamba remove --quiet --channel conda-forge --force fipy displayName: Install Anaconda packages - bash: | From cecd184ef6b51489f58708996d1c5ac64c02aa72 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 11:07:37 -0400 Subject: [PATCH 027/175] Just install fipy --- .azure/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 3ef717339e..d69560210f 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -13,7 +13,7 @@ jobs: Python27: python.version: '2.7' Python36: - python.version: '3.6' + python.version: '3.9' steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" @@ -24,7 +24,7 @@ jobs: - bash: | source activate myEnvironment - mamba install --channel conda-forge python=$PYTHON_VERSION fipy pytrilinos gmsh + mamba install --channel conda-forge python=$PYTHON_VERSION fipy mamba remove --quiet --channel conda-forge --force fipy displayName: Install Anaconda packages - bash: | From 306f2ea8f9b778a2f3a8328420253066a01a391f Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 11:09:04 -0400 Subject: [PATCH 028/175] Fix strategy name --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index d69560210f..054a2e4d4c 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -12,7 +12,7 @@ jobs: matrix: Python27: python.version: '2.7' - Python36: + Python39: python.version: '3.9' steps: From d79440bd71c1ea2b29079bce318d3e55fb35005d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 11:54:58 -0400 Subject: [PATCH 029/175] Split mamba installation into two steps --- .azure/pipelines.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 054a2e4d4c..02a6db2ec7 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -25,8 +25,11 @@ jobs: - bash: | source activate myEnvironment mamba install --channel conda-forge python=$PYTHON_VERSION fipy - mamba remove --quiet --channel conda-forge --force fipy displayName: Install Anaconda packages + - bash: | + source activate myEnvironment + mamba remove --quiet --channel conda-forge --force fipy + displayName: Remove Anaconda packages - bash: | source activate myEnvironment pip install scikit-fmm From cbd593f29bbaf6100f5b6a8b579bb27cce77370a Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 12:02:23 -0400 Subject: [PATCH 030/175] Tell mamba yes --- .azure/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 02a6db2ec7..410779ad44 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,11 +24,11 @@ jobs: - bash: | source activate myEnvironment - mamba install --channel conda-forge python=$PYTHON_VERSION fipy + mamba install --quiet --yes --channel conda-forge python=$PYTHON_VERSION fipy displayName: Install Anaconda packages - bash: | source activate myEnvironment - mamba remove --quiet --channel conda-forge --force fipy + mamba remove --quiet --yes --channel conda-forge --force fipy displayName: Remove Anaconda packages - bash: | source activate myEnvironment From 3f4d93076db0b996a4255113d041d835e9de4330 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 21:56:14 -0400 Subject: [PATCH 031/175] Install fipy prereqs w/o fipy --- .azure/pipelines.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 410779ad44..75b54d2222 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,12 +24,8 @@ jobs: - bash: | source activate myEnvironment - mamba install --quiet --yes --channel conda-forge python=$PYTHON_VERSION fipy + mamba install --quiet --yes --channel conda-forge --only-deps python=$PYTHON_VERSION fipy displayName: Install Anaconda packages - - bash: | - source activate myEnvironment - mamba remove --quiet --yes --channel conda-forge --force fipy - displayName: Remove Anaconda packages - bash: | source activate myEnvironment pip install scikit-fmm From 622eecdde084deda69d1f0bf91ecc8ea57c95142 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 22:11:19 -0400 Subject: [PATCH 032/175] Add prereqs --- .azure/pipelines.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 75b54d2222..892818fb49 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,12 +24,14 @@ jobs: - bash: | source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$PYTHON_VERSION fipy + mamba install --quiet --yes --channel conda-forge --only-deps python=${{ python.version }} fipy pytrilinos gmsh displayName: Install Anaconda packages + - bash: | source activate myEnvironment pip install scikit-fmm displayName: Install pip packages + - bash: | source activate myEnvironment python setup.py egg_info From a138f5f34e97d257830db3c0bb6d887a92310f9d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 22:14:23 -0400 Subject: [PATCH 033/175] Fix matrix variable --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 892818fb49..d8a17726fc 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,7 +24,7 @@ jobs: - bash: | source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=${{ python.version }} fipy pytrilinos gmsh + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy pytrilinos gmsh displayName: Install Anaconda packages - bash: | From 0cf512bdc60f11a9ccadad1409d85d7bda262a36 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 22:18:08 -0400 Subject: [PATCH 034/175] Remove pytrilinos --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index d8a17726fc..f0582d43b1 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -24,7 +24,7 @@ jobs: - bash: | source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy pytrilinos gmsh + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy gmsh displayName: Install Anaconda packages - bash: | From 542e68d870cc6754a9ef646b0f14a8e33a83ac46 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 23 Sep 2021 22:21:03 -0400 Subject: [PATCH 035/175] Install gmsh separately --- .azure/pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f0582d43b1..e90ddc4111 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -25,6 +25,7 @@ jobs: - bash: | source activate myEnvironment mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy gmsh + mamba install --quiet --yes --channel conda-forge gmsh displayName: Install Anaconda packages - bash: | From 1a10697c728c055d627bccf8accf49ad13891440 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 09:48:45 -0400 Subject: [PATCH 036/175] Install different packages for different Pythons --- .azure/pipelines.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index e90ddc4111..f75a3efe84 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -7,13 +7,15 @@ jobs: - job: displayName: ubuntu-16.04 pool: - vmImage: 'ubuntu-16.04' + vmImage: 'ubuntu-latest' strategy: matrix: Python27: python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' Python39: python.version: '3.9' + conda.packages: 'gmsh' steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" @@ -24,8 +26,8 @@ jobs: - bash: | source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy gmsh - mamba install --quiet --yes --channel conda-forge gmsh + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy + mamba install --quiet --yes --channel conda-forge $(conda.packages) displayName: Install Anaconda packages - bash: | From 8837415dca558d3d920542c3643b1deb2a68d047 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 12:52:22 -0400 Subject: [PATCH 037/175] Add linux install template --- .azure/templates/install_linux.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .azure/templates/install_linux.yml diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_linux.yml new file mode 100644 index 0000000000..9d689ec74f --- /dev/null +++ b/.azure/templates/install_linux.yml @@ -0,0 +1,23 @@ +paramters: +- name: python.version + default: 3.9 +- name: conda.packages + default: '' + +steps: + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH + + - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba + displayName: Create Anaconda environment + + - bash: | + source activate myEnvironment + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy + mamba install --quiet --yes --channel conda-forge $(conda.packages) + displayName: Install Anaconda packages + + - bash: | + source activate myEnvironment + pip install scikit-fmm + displayName: Install pip packages From 1b62e4529ae3dcfd46dc2b0de7ada3c2f35d7faf Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 12:55:22 -0400 Subject: [PATCH 038/175] Template install --- .azure/pipelines.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f75a3efe84..061741d408 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -18,22 +18,10 @@ jobs: conda.packages: 'gmsh' steps: - - bash: echo "##vso[task.prependpath]$CONDA/bin" - displayName: Add conda to PATH - - - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba - displayName: Create Anaconda environment - - - bash: | - source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy - mamba install --quiet --yes --channel conda-forge $(conda.packages) - displayName: Install Anaconda packages - - - bash: | - source activate myEnvironment - pip install scikit-fmm - displayName: Install pip packages + - template: templates/install_linux.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) - bash: | source activate myEnvironment From e8a61739ee070580a532e98f6c6660564b05e9ec Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 15:50:17 -0400 Subject: [PATCH 039/175] Fix typo --- .azure/templates/install_linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_linux.yml index 9d689ec74f..e7918c38cb 100644 --- a/.azure/templates/install_linux.yml +++ b/.azure/templates/install_linux.yml @@ -1,4 +1,4 @@ -paramters: +parameters: - name: python.version default: 3.9 - name: conda.packages From 5bcd53c07927cc75c6aac5d4741e4bd075481b76 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 16:22:08 -0400 Subject: [PATCH 040/175] Add macOS setup step --- .azure/templates/install_linux.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_linux.yml index e7918c38cb..54a8522fca 100644 --- a/.azure/templates/install_linux.yml +++ b/.azure/templates/install_linux.yml @@ -1,4 +1,6 @@ parameters: +- name: platform + default: 'linux' - name: python.version default: 3.9 - name: conda.packages @@ -7,6 +9,12 @@ parameters: steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH + + # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ + # We need to take ownership if we want to update conda or install packages globally + - ${{ if eq(parameters.platform, "macos") }}: + - bash: |sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment From 1f7b1c20417cb6a886a6e20b87034d41eb3c5a5f Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 16:22:23 -0400 Subject: [PATCH 041/175] Introduce macOS builds --- .azure/pipelines.yml | 55 ++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 061741d408..4cf87a9ff4 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -3,28 +3,37 @@ # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: # https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/anaconda -jobs: -- job: - displayName: ubuntu-16.04 - pool: - vmImage: 'ubuntu-latest' - strategy: - matrix: - Python27: - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - Python39: - python.version: '3.9' - conda.packages: 'gmsh' +strategy: + matrix: + linux-py27: + platform: 'ubuntu' + python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + linux-py39: + platform: 'ubuntu' + python.version: '3.9' + conda.packages: 'gmsh' + macos-py27: + platform: 'macos' + python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + macos-py39: + platform: 'macos' + python.version: '3.9' + conda.packages: 'gmsh' - steps: - - template: templates/install_linux.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) +pool: + vmImage: $(platform)-latest - - bash: | - source activate myEnvironment - python setup.py egg_info - python setup.py test --deprecation-errors - displayName: test +steps: +- template: templates/install_linux.yml + parameters: + platform: $(platform) + python.version: $(python.version) + conda.packages: $(conda.packages) + +- bash: | + source activate myEnvironment + python setup.py egg_info + python setup.py test --deprecation-errors + displayName: test From d6775098e96bb61efa197374e4db8fcd6ce29b61 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 18:54:22 -0400 Subject: [PATCH 042/175] Fix typo --- .azure/templates/install_linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_linux.yml index 54a8522fca..dad43c7d37 100644 --- a/.azure/templates/install_linux.yml +++ b/.azure/templates/install_linux.yml @@ -13,7 +13,7 @@ steps: # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ # We need to take ownership if we want to update conda or install packages globally - ${{ if eq(parameters.platform, "macos") }}: - - bash: |sudo chown -R $USER $CONDA + - bash: sudo chown -R $USER $CONDA displayName: Take ownership of conda installation - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba From cc3869030ab15adb89ffbaa0132916124e899985 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 18:56:46 -0400 Subject: [PATCH 043/175] Change to single quotes --- .azure/templates/install_linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_linux.yml index dad43c7d37..9329654730 100644 --- a/.azure/templates/install_linux.yml +++ b/.azure/templates/install_linux.yml @@ -12,7 +12,7 @@ steps: # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ # We need to take ownership if we want to update conda or install packages globally - - ${{ if eq(parameters.platform, "macos") }}: + - ${{ if eq(parameters.platform, 'macos') }}: - bash: sudo chown -R $USER $CONDA displayName: Take ownership of conda installation From b8e8df80f6b7ad2d3d3dde559f8d8ce820f67141 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 19:09:14 -0400 Subject: [PATCH 044/175] Take out macos step --- .azure/templates/install_linux.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_linux.yml index 9329654730..ec7cc82d84 100644 --- a/.azure/templates/install_linux.yml +++ b/.azure/templates/install_linux.yml @@ -10,12 +10,6 @@ steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH - # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ - # We need to take ownership if we want to update conda or install packages globally - - ${{ if eq(parameters.platform, 'macos') }}: - - bash: sudo chown -R $USER $CONDA - displayName: Take ownership of conda installation - - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment From f3d94c778d176fb78d057b18aba1100220f7e455 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 19:10:15 -0400 Subject: [PATCH 045/175] Move macos step to pipeline.yml --- .azure/pipelines.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 4cf87a9ff4..81852d0266 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,6 +26,12 @@ pool: vmImage: $(platform)-latest steps: +# On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ +# We need to take ownership if we want to update conda or install packages globally +- ${{ if eq(platform, 'macos') }}: + - bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + - template: templates/install_linux.yml parameters: platform: $(platform) From 76c1c8ef7a325df6d50805dc3f0dbbe8ef01c4d2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 19:22:02 -0400 Subject: [PATCH 046/175] Fix condition(?) --- .azure/pipelines.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 81852d0266..2937253450 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -28,9 +28,9 @@ pool: steps: # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ # We need to take ownership if we want to update conda or install packages globally -- ${{ if eq(platform, 'macos') }}: - - bash: sudo chown -R $USER $CONDA - displayName: Take ownership of conda installation +- bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + condition: eq(platform, 'macos') - template: templates/install_linux.yml parameters: From adab2c8e0e82981654f45197fa2e3624388742f1 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 19:24:09 -0400 Subject: [PATCH 047/175] Microsoft is whack --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 2937253450..140bc53439 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -30,7 +30,7 @@ steps: # We need to take ownership if we want to update conda or install packages globally - bash: sudo chown -R $USER $CONDA displayName: Take ownership of conda installation - condition: eq(platform, 'macos') + condition: eq($(platform), 'macos') - template: templates/install_linux.yml parameters: From c6f48ae925971c5c6a777a8a785b96707a49c12a Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 24 Sep 2021 19:28:44 -0400 Subject: [PATCH 048/175] What an utterly batty syntax --- .azure/pipelines.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 140bc53439..1c614a76fc 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -22,6 +22,9 @@ strategy: python.version: '3.9' conda.packages: 'gmsh' +variables: + isMacOS: $[eq(platform, 'macos')] + pool: vmImage: $(platform)-latest @@ -30,7 +33,7 @@ steps: # We need to take ownership if we want to update conda or install packages globally - bash: sudo chown -R $USER $CONDA displayName: Take ownership of conda installation - condition: eq($(platform), 'macos') + condition: eq(variables.isMacOS, 'true') - template: templates/install_linux.yml parameters: From 39d83ddcebcb993ab3df8a9d2a65dc091ab4bad5 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:07:39 -0400 Subject: [PATCH 049/175] Refactor ubuntu and macos installations --- .azure/pipelines.yml | 6 +----- .../templates/{install_linux.yml => install_bash.yml} | 2 -- .azure/templates/install_macos.yml | 0 .azure/templates/install_ubuntu.yml | 11 +++++++++++ 4 files changed, 12 insertions(+), 7 deletions(-) rename .azure/templates/{install_linux.yml => install_bash.yml} (95%) create mode 100644 .azure/templates/install_macos.yml create mode 100644 .azure/templates/install_ubuntu.yml diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 1c614a76fc..93eae8b135 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -22,9 +22,6 @@ strategy: python.version: '3.9' conda.packages: 'gmsh' -variables: - isMacOS: $[eq(platform, 'macos')] - pool: vmImage: $(platform)-latest @@ -35,9 +32,8 @@ steps: displayName: Take ownership of conda installation condition: eq(variables.isMacOS, 'true') -- template: templates/install_linux.yml +- template: templates/install_$(platform).yml parameters: - platform: $(platform) python.version: $(python.version) conda.packages: $(conda.packages) diff --git a/.azure/templates/install_linux.yml b/.azure/templates/install_bash.yml similarity index 95% rename from .azure/templates/install_linux.yml rename to .azure/templates/install_bash.yml index ec7cc82d84..c1ed98a951 100644 --- a/.azure/templates/install_linux.yml +++ b/.azure/templates/install_bash.yml @@ -1,6 +1,4 @@ parameters: -- name: platform - default: 'linux' - name: python.version default: 3.9 - name: conda.packages diff --git a/.azure/templates/install_macos.yml b/.azure/templates/install_macos.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.azure/templates/install_ubuntu.yml b/.azure/templates/install_ubuntu.yml new file mode 100644 index 0000000000..47571a2870 --- /dev/null +++ b/.azure/templates/install_ubuntu.yml @@ -0,0 +1,11 @@ +parameters: +- name: python.version + default: 3.9 +- name: conda.packages + default: '' + +steps: +- template: install_bash.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) From e243b2fda2f6adc98b7bbde5100ef0e9e62ed15e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:10:45 -0400 Subject: [PATCH 050/175] Try to figure out compile-time vs run-time variables --- .azure/pipelines.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 93eae8b135..3186121bbc 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,13 +26,7 @@ pool: vmImage: $(platform)-latest steps: -# On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ -# We need to take ownership if we want to update conda or install packages globally -- bash: sudo chown -R $USER $CONDA - displayName: Take ownership of conda installation - condition: eq(variables.isMacOS, 'true') - -- template: templates/install_$(platform).yml +- template: templates/install_${{ platform }}.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From 2591a735cd227ce571e57836736f7e29219f81a4 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:13:31 -0400 Subject: [PATCH 051/175] More fiddling with azure variables --- .azure/pipelines.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 3186121bbc..ab0e5d2151 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -25,8 +25,11 @@ strategy: pool: vmImage: $(platform)-latest +variables: + platform: $(platform) + steps: -- template: templates/install_${{ platform }}.yml +- template: templates/install_${{ variables.platform }}.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From da3ac9a689dc7ad5e649d538d7d7ea8e3405b6ab Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:14:55 -0400 Subject: [PATCH 052/175] More more fiddling with azure variables --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index ab0e5d2151..98851cbf86 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -29,7 +29,7 @@ variables: platform: $(platform) steps: -- template: templates/install_${{ variables.platform }}.yml +- template: templates/install_$[ platform ].yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From e33fc02f71871b9e6dac655c6c84ec9049108e26 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:15:58 -0400 Subject: [PATCH 053/175] More more more --- .azure/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 98851cbf86..ada6b7acf0 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,10 +26,10 @@ pool: vmImage: $(platform)-latest variables: - platform: $(platform) + platform: $[ platform ] steps: -- template: templates/install_$[ platform ].yml +- template: templates/install_${{ variables.platform }}.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From e867408c6d57bc2470eb865d0905e347dfe045ee Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:17:18 -0400 Subject: [PATCH 054/175] More**4 --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index ada6b7acf0..fd5763576e 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,7 +26,7 @@ pool: vmImage: $(platform)-latest variables: - platform: $[ platform ] + platform: ${{ platform }} steps: - template: templates/install_${{ variables.platform }}.yml From d3bfbea9a387f0b43f1acfe4b8649a81d17f3768 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:29:41 -0400 Subject: [PATCH 055/175] More**5 --- .azure/pipelines.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index fd5763576e..2cec97a836 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -25,11 +25,8 @@ strategy: pool: vmImage: $(platform)-latest -variables: - platform: ${{ platform }} - steps: -- template: templates/install_${{ variables.platform }}.yml +- template: templates/install_$[ variables['platform'] ].yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From 3c11074528fa7e40c0e7abb891dcbeec8cdca999 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:31:06 -0400 Subject: [PATCH 056/175] More**6 --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 2cec97a836..20b04a14c9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,7 +26,7 @@ pool: vmImage: $(platform)-latest steps: -- template: templates/install_$[ variables['platform'] ].yml +- template: templates/install_${{ variables['platform'] }}.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From fc98180c1aaad22bfef4bc29eead1ce15bbee6e8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:42:26 -0400 Subject: [PATCH 057/175] Try to select template at runtime --- .azure/pipelines.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 20b04a14c9..07d934a79f 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,10 +26,17 @@ pool: vmImage: $(platform)-latest steps: -- template: templates/install_${{ variables['platform'] }}.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) +- ${{ if eq(platform, 'ubuntu) }}: + - template: templates/install_ubuntu.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) + +- ${{ if eq(platform, 'macos) }}: + - template: templates/install_macos.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) - bash: | source activate myEnvironment From 9ef13e67223621d401ab12d76982e6e92a97e957 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:43:47 -0400 Subject: [PATCH 058/175] Fix typos --- .azure/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 07d934a79f..3cca301f10 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,13 +26,13 @@ pool: vmImage: $(platform)-latest steps: -- ${{ if eq(platform, 'ubuntu) }}: +- ${{ if eq(platform, 'ubuntu') }}: - template: templates/install_ubuntu.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) -- ${{ if eq(platform, 'macos) }}: +- ${{ if eq(platform, 'macos') }}: - template: templates/install_macos.yml parameters: python.version: $(python.version) From 06171cca7d2a64b56ad1e8a9b44d3e60713e33ed Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:46:32 -0400 Subject: [PATCH 059/175] Trying to access matrix variables at runtime --- .azure/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 3cca301f10..165736caf2 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,13 +26,13 @@ pool: vmImage: $(platform)-latest steps: -- ${{ if eq(platform, 'ubuntu') }}: +- ${{ if eq(variables.platform, 'ubuntu') }}: - template: templates/install_ubuntu.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) -- ${{ if eq(platform, 'macos') }}: +- ${{ if eq(variables.platform, 'macos') }}: - template: templates/install_macos.yml parameters: python.version: $(python.version) From a4ecab242d2a5ca016735f5a744b0551831f65c3 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 10:59:18 -0400 Subject: [PATCH 060/175] Use matrix variables at compile time See https://developercommunity.visualstudio.com/t/matrix-variable-that-is-passed-to-a-template-as-a/1184356 --- .azure/pipelines.yml | 15 ++++----------- .azure/templates/install_bash.yml | 6 ++++++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 165736caf2..48ce0e21ca 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -26,17 +26,10 @@ pool: vmImage: $(platform)-latest steps: -- ${{ if eq(variables.platform, 'ubuntu') }}: - - template: templates/install_ubuntu.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) - -- ${{ if eq(variables.platform, 'macos') }}: - - template: templates/install_macos.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) +- template: templates/install_bash.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) - bash: | source activate myEnvironment diff --git a/.azure/templates/install_bash.yml b/.azure/templates/install_bash.yml index c1ed98a951..968f695d54 100644 --- a/.azure/templates/install_bash.yml +++ b/.azure/templates/install_bash.yml @@ -7,6 +7,12 @@ parameters: steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH + + # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ + # We need to take ownership if we want to update conda or install packages globally + - bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + condition: eq(variables.platform, 'macos') - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment From 1302e0b534e7624d28488805662f0e2f36791ed9 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:13:06 -0400 Subject: [PATCH 061/175] Fix or syntax --- .azure/templates/install.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .azure/templates/install.yml diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml new file mode 100644 index 0000000000..7734a4b763 --- /dev/null +++ b/.azure/templates/install.yml @@ -0,0 +1,9 @@ +parameters: +- name: python.version + default: 3.9 +- name: conda.packages + default: '' + +steps: + - template: install_bash.yml + condition: or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) From 23b4c5bccc9dccf5a00f896e3f0b2ff07eb48690 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:15:13 -0400 Subject: [PATCH 062/175] Add windows build --- .azure/pipelines.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 48ce0e21ca..af8e70b0c9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -21,12 +21,16 @@ strategy: platform: 'macos' python.version: '3.9' conda.packages: 'gmsh' + windows-py39: + platform: 'windows' + python.version: '3.9' + conda.packages: 'gmsh' pool: vmImage: $(platform)-latest steps: -- template: templates/install_bash.yml +- template: templates/install.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) From a58d607f994176cfddb8cef2b034c82c48f351d3 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:19:24 -0400 Subject: [PATCH 063/175] Fix conditional syntax https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops#parameters-to-select-a-template-at-runtime --- .azure/templates/install.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 7734a4b763..94a9e6d27f 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -5,5 +5,5 @@ parameters: default: '' steps: - - template: install_bash.yml - condition: or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) + - ${{ if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }} + - template: install_bash.yml From 8b575d444539ba0366ab492e8138bcb3eb603d84 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:21:14 -0400 Subject: [PATCH 064/175] Fix the fix --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 94a9e6d27f..061b0f61cb 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -5,5 +5,5 @@ parameters: default: '' steps: - - ${{ if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }} + - ${{ if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }}: - template: install_bash.yml From 1a20fd9530b1240ab7eec385d43e4bfca51bc8b9 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:24:28 -0400 Subject: [PATCH 065/175] What a mess --- .azure/templates/install.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 061b0f61cb..a948a2bd90 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,9 +1,11 @@ parameters: +- name: platform + default: '' - name: python.version default: 3.9 - name: conda.packages default: '' steps: - - ${{ if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }}: + - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From 66088323a25570b61900df3c8b81654306d12fa7 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:27:56 -0400 Subject: [PATCH 066/175] Pass platform to template --- .azure/pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index af8e70b0c9..24bcf95495 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -32,6 +32,7 @@ pool: steps: - template: templates/install.yml parameters: + platform: $(platform) python.version: $(python.version) conda.packages: $(conda.packages) From f560aa712375d68f38c1d9129f7a5429032c726f Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 11:50:53 -0400 Subject: [PATCH 067/175] Add logging --- .azure/pipelines.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 24bcf95495..044a204d34 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -29,6 +29,10 @@ strategy: pool: vmImage: $(platform)-latest +variables: + - name: system.log + value: true + steps: - template: templates/install.yml parameters: From 2e4b12a28537f49c0a17b4b64f1d0922778837d2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 22:05:02 -0400 Subject: [PATCH 068/175] Add diagnostic --- .azure/templates/install.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index a948a2bd90..2d8e3b0620 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,5 +7,8 @@ parameters: default: '' steps: + - bash: echo $(parameters.platform) + displayName: Echo + - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From 512885ccdd071cb5d772012f6243bba4bdb963c2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 22:07:19 -0400 Subject: [PATCH 069/175] Fix syntax --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 2d8e3b0620..73f05fa6c2 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,7 +7,7 @@ parameters: default: '' steps: - - bash: echo $(parameters.platform) + - bash: echo ${{ parameters.platform }} displayName: Echo - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From a0306fcb20b1207414ca56f01f58e86711b497eb Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 22:10:12 -0400 Subject: [PATCH 070/175] Echo lots of stuff --- .azure/templates/install.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 73f05fa6c2..13a7d15c71 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -8,7 +8,16 @@ parameters: steps: - bash: echo ${{ parameters.platform }} - displayName: Echo + displayName: Echo 1 + + - bash: echo ${{ eq(parameters.platform, 'macos') }} + displayName: Echo 2 + + - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} + displayName: Echo 3 + + - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From 75b1aa20a71f87efcfa773806c756c53ebb7038f Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 22:22:46 -0400 Subject: [PATCH 071/175] Echo some new stuff --- .azure/templates/install.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 13a7d15c71..014ab30f4b 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,18 +6,16 @@ parameters: - name: conda.packages default: '' +variables: + platform: ${{ parameters.platform }} + isBash: $[or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu'))] + steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ eq(parameters.platform, 'macos') }} + - bash: echo $(isBash) displayName: Echo 2 - - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} - displayName: Echo 3 - - - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} - displayName: Echo 4 - - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From 4eabe3d03a08b8f525d4b4a53aa222922e8289cd Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sat, 25 Sep 2021 22:25:09 -0400 Subject: [PATCH 072/175] Why is this syntax so stupid? --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 014ab30f4b..76c7044b1c 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -8,7 +8,7 @@ parameters: variables: platform: ${{ parameters.platform }} - isBash: $[or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu'))] + isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: - bash: echo ${{ parameters.platform }} From 650430ead10c5798db05510a673aadd6b611e8d2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 21:39:10 -0400 Subject: [PATCH 073/175] Use variable --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 76c7044b1c..621c297950 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -17,5 +17,5 @@ steps: - bash: echo $(isBash) displayName: Echo 2 - - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: + - ${{ isBash }}: - template: install_bash.yml From 288a23c818a5d3b7ad7cfab22b30b6b2af14ff55 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 21:42:16 -0400 Subject: [PATCH 074/175] Pass isBash as parameter --- .azure/pipelines.yml | 5 +++-- .azure/templates/install.yml | 6 ++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 044a204d34..1b4dadce22 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -30,13 +30,14 @@ pool: vmImage: $(platform)-latest variables: - - name: system.log - value: true + system.log: true + isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: - template: templates/install.yml parameters: platform: $(platform) + isBash: $[isBash] python.version: $(python.version) conda.packages: $(conda.packages) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 621c297950..d4367e1588 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -5,10 +5,8 @@ parameters: default: 3.9 - name: conda.packages default: '' - -variables: - platform: ${{ parameters.platform }} - isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] +- name: isBash + default: false steps: - bash: echo ${{ parameters.platform }} From aff4c2ee83199aef69b3195df95251153155ebe1 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 21:44:11 -0400 Subject: [PATCH 075/175] Read isBash as parameter --- .azure/templates/install.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index d4367e1588..19a1c201a3 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -12,8 +12,8 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo $(isBash) + - bash: echo ${{ parameters.isBash) } displayName: Echo 2 - - ${{ isBash }}: + - ${{ if parameters.isBash }}: - template: install_bash.yml From 15a53ba757635bb3165fc65e63eb2de001fb5473 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 21:45:47 -0400 Subject: [PATCH 076/175] Fix typo --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 19a1c201a3..f3008256b8 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -12,7 +12,7 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.isBash) } + - bash: echo ${{ parameters.isBash }} displayName: Echo 2 - ${{ if parameters.isBash }}: From d22edc7f3a49d4e8bd16cfc73671b0c6b5638c47 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 21:57:00 -0400 Subject: [PATCH 077/175] Debug? --- .azure/pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 1b4dadce22..7dbfa219e8 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -30,6 +30,7 @@ pool: vmImage: $(platform)-latest variables: + system.debug: true system.log: true isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] From 40f65cd0d0be6912ec93992ffedd6f8a816c3767 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 21:58:20 -0400 Subject: [PATCH 078/175] Comment out troublesome expression --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 7dbfa219e8..222773c232 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -32,7 +32,7 @@ pool: variables: system.debug: true system.log: true - isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] +# isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: - template: templates/install.yml From 1d96e5fb6562be3438775eb6c85c7af3a25f4bae Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 22:36:50 -0400 Subject: [PATCH 079/175] Switch back to platform.parameters --- .azure/pipelines.yml | 1 - .azure/templates/install.yml | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 222773c232..61ec528994 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -38,7 +38,6 @@ steps: - template: templates/install.yml parameters: platform: $(platform) - isBash: $[isBash] python.version: $(python.version) conda.packages: $(conda.packages) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index f3008256b8..13a7d15c71 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -5,15 +5,19 @@ parameters: default: 3.9 - name: conda.packages default: '' -- name: isBash - default: false steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.isBash }} + - bash: echo ${{ eq(parameters.platform, 'macos') }} displayName: Echo 2 - - ${{ if parameters.isBash }}: + - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} + displayName: Echo 3 + + - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + displayName: Echo 4 + + - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From ec4b84fc0f8ecc0db112d98c03027867f3a2e915 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 22:42:51 -0400 Subject: [PATCH 080/175] Change parameters syntax --- .azure/templates/install_macos.yml | 0 .azure/templates/install_ubuntu.yml | 11 ----------- 2 files changed, 11 deletions(-) delete mode 100644 .azure/templates/install_macos.yml delete mode 100644 .azure/templates/install_ubuntu.yml diff --git a/.azure/templates/install_macos.yml b/.azure/templates/install_macos.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.azure/templates/install_ubuntu.yml b/.azure/templates/install_ubuntu.yml deleted file mode 100644 index 47571a2870..0000000000 --- a/.azure/templates/install_ubuntu.yml +++ /dev/null @@ -1,11 +0,0 @@ -parameters: -- name: python.version - default: 3.9 -- name: conda.packages - default: '' - -steps: -- template: install_bash.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) From 6d247623588d149e29f0e6ca6b190ab87d174cd2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 22:43:21 -0400 Subject: [PATCH 081/175] Change parameters syntax --- .azure/templates/install.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 13a7d15c71..c7d0b9d17b 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,10 +1,7 @@ parameters: -- name: platform - default: '' -- name: python.version - default: 3.9 -- name: conda.packages - default: '' + platform: '' + python.version: 3.9 + conda.packages: '' steps: - bash: echo ${{ parameters.platform }} From 32b5a13467df74c7fa9b644022325594faf370fa Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 22:46:22 -0400 Subject: [PATCH 082/175] Add diagnostics --- .azure/templates/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index c7d0b9d17b..0237acd7f4 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,13 +7,13 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ eq(parameters.platform, 'macos') }} + - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'macos') }} displayName: Echo 2 - - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} + - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'ubuntu') }} displayName: Echo 3 - - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + - bash: echo ${{ parameters.platform }} ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From 4be3727b76f0b5fd33b0c3e920210d89e6f92431 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 22:57:00 -0400 Subject: [PATCH 083/175] Mix compile time and run time --- .azure/templates/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 0237acd7f4..cb8db3c9d9 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,13 +7,13 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'macos') }} + - bash: echo ${{ parameters.platform }} $[ eq(${{ parameters.platform }}, 'macos') ] displayName: Echo 2 - - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'ubuntu') }} + - bash: echo ${{ parameters.platform }} $[ eq(${{ parameters.platform }}, 'ubuntu') ] displayName: Echo 3 - - bash: echo ${{ parameters.platform }} ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + - bash: echo ${{ parameters.platform }} $[ or(eq(${{ parameters.platform }}, 'macos'), eq(${{ parameters.platform }}, 'ubuntu')) }} displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From 1420e3f98beee35463ab1427c7098db4445578cb Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:00:15 -0400 Subject: [PATCH 084/175] Try some quotes --- .azure/templates/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index cb8db3c9d9..170aaba01d 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,13 +7,13 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.platform }} $[ eq(${{ parameters.platform }}, 'macos') ] + - bash: echo ${{ parameters.platform }} $[ eq('${{ parameters.platform }}', 'macos') ] displayName: Echo 2 - - bash: echo ${{ parameters.platform }} $[ eq(${{ parameters.platform }}, 'ubuntu') ] + - bash: echo ${{ parameters.platform }} $[ eq('${{ parameters.platform }}', 'ubuntu') ] displayName: Echo 3 - - bash: echo ${{ parameters.platform }} $[ or(eq(${{ parameters.platform }}, 'macos'), eq(${{ parameters.platform }}, 'ubuntu')) }} + - bash: echo ${{ parameters.platform }} $[ or(eq('${{ parameters.platform }}', 'macos'), eq('${{ parameters.platform }}', 'ubuntu')) }} displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From 95871da73b439bd70f2087551786af3752d97ebe Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:05:48 -0400 Subject: [PATCH 085/175] Microsoft are full of crap --- .azure/templates/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 170aaba01d..e39d3b9069 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,13 +7,13 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.platform }} $[ eq('${{ parameters.platform }}', 'macos') ] + - bash: echo ${{ parameters.platform }} ${{ eq('parameters.platform', 'macos') }} displayName: Echo 2 - - bash: echo ${{ parameters.platform }} $[ eq('${{ parameters.platform }}', 'ubuntu') ] + - bash: echo ${{ parameters.platform }} ${{ eq('parameters.platform', 'ubuntu') }} displayName: Echo 3 - - bash: echo ${{ parameters.platform }} $[ or(eq('${{ parameters.platform }}', 'macos'), eq('${{ parameters.platform }}', 'ubuntu')) }} + - bash: echo ${{ parameters.platform }} ${{ or(eq('parameters.platform', 'macos'), eq('parameters.platform', 'ubuntu')) }} displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From ec553d867212452ebcf0f4e593c10e29bf679580 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:15:03 -0400 Subject: [PATCH 086/175] Add more diagnostics --- .azure/pipelines.yml | 12 ++++++++++++ .azure/templates/install.yml | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 61ec528994..f6b4ae72e4 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -35,6 +35,18 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: +- bash: echo ${{ platform }} + displayName: Echo 1a + +- bash: echo ${{ platform }} ${{ eq(platform, 'macos') }} + displayName: Echo 2a + +- bash: echo ${{ platform }} ${{ eq(platform, 'ubuntu') }} + displayName: Echo 3a + +- bash: echo ${{ platform }} ${{ or(eq(platform, 'macos'), eq(platform, 'ubuntu')) }} + displayName: Echo 4a + - template: templates/install.yml parameters: platform: $(platform) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index e39d3b9069..0237acd7f4 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -7,13 +7,13 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.platform }} ${{ eq('parameters.platform', 'macos') }} + - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'macos') }} displayName: Echo 2 - - bash: echo ${{ parameters.platform }} ${{ eq('parameters.platform', 'ubuntu') }} + - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'ubuntu') }} displayName: Echo 3 - - bash: echo ${{ parameters.platform }} ${{ or(eq('parameters.platform', 'macos'), eq('parameters.platform', 'ubuntu')) }} + - bash: echo ${{ parameters.platform }} ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From 4835d13aa445e8b221da7e586067fa832c685878 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:16:38 -0400 Subject: [PATCH 087/175] Runtime? --- .azure/pipelines.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f6b4ae72e4..1a79059bf7 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -35,16 +35,16 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: -- bash: echo ${{ platform }} +- bash: echo $[ platform ] displayName: Echo 1a -- bash: echo ${{ platform }} ${{ eq(platform, 'macos') }} +- bash: echo $[ platform ] $[ eq(platform, 'macos') ] displayName: Echo 2a -- bash: echo ${{ platform }} ${{ eq(platform, 'ubuntu') }} +- bash: echo $[ platform ] $[ eq(platform, 'ubuntu') ] displayName: Echo 3a -- bash: echo ${{ platform }} ${{ or(eq(platform, 'macos'), eq(platform, 'ubuntu')) }} +- bash: echo $[ platform ] $[ or(eq(platform, 'macos'), eq(platform, 'ubuntu')) ] displayName: Echo 4a - template: templates/install.yml From 2fe785917a6e879ce00099217a90cb54a79bc6b0 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:18:45 -0400 Subject: [PATCH 088/175] ??? --- .azure/pipelines.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 1a79059bf7..1a9c019260 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -35,16 +35,16 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: -- bash: echo $[ platform ] +- bash: echo $(platform) displayName: Echo 1a -- bash: echo $[ platform ] $[ eq(platform, 'macos') ] +- bash: echo $(platform) $[ eq($(platform), 'macos') ] displayName: Echo 2a -- bash: echo $[ platform ] $[ eq(platform, 'ubuntu') ] +- bash: echo $(platform) $[ eq($(platform), 'ubuntu') ] displayName: Echo 3a -- bash: echo $[ platform ] $[ or(eq(platform, 'macos'), eq(platform, 'ubuntu')) ] +- bash: echo $(platform) $[ or(eq($(platform), 'macos'), eq($(platform), 'ubuntu')) ] displayName: Echo 4a - template: templates/install.yml From 039e3568e97c819c2884588d77771da564e300c1 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:20:47 -0400 Subject: [PATCH 089/175] Quotes --- .azure/pipelines.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 1a9c019260..83009c9cc0 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -38,13 +38,13 @@ steps: - bash: echo $(platform) displayName: Echo 1a -- bash: echo $(platform) $[ eq($(platform), 'macos') ] +- bash: echo $(platform) $[ eq('$(platform)', 'macos') ] displayName: Echo 2a -- bash: echo $(platform) $[ eq($(platform), 'ubuntu') ] +- bash: echo $(platform) $[ eq('$(platform)', 'ubuntu') ] displayName: Echo 3a -- bash: echo $(platform) $[ or(eq($(platform), 'macos'), eq($(platform), 'ubuntu')) ] +- bash: echo $(platform) $[ or(eq('$(platform)', 'macos'), eq('$(platform)', 'ubuntu')) ] displayName: Echo 4a - template: templates/install.yml From b387fbf13d97d2f77df60e5dc3b07f12325ef27e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:27:42 -0400 Subject: [PATCH 090/175] Add conditional template --- .azure/pipelines.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 83009c9cc0..efbd98de32 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -35,6 +35,9 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: +- ${{ if or(eq(platform, 'macos'), eq(platform, 'ubuntu')) }}: + - template: templates/install_bash.yml + - bash: echo $(platform) displayName: Echo 1a From 33220b4933eb59ee8cfcb2ecf8e6d4f207ed26fc Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:29:09 -0400 Subject: [PATCH 091/175] I hate this crap --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index efbd98de32..87150d0796 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -35,7 +35,7 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: -- ${{ if or(eq(platform, 'macos'), eq(platform, 'ubuntu')) }}: +- $[ if or(eq(platform, 'macos'), eq(platform, 'ubuntu')) ]: - template: templates/install_bash.yml - bash: echo $(platform) From a83396186e0362da345ec2437314ecba1e94595a Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:31:44 -0400 Subject: [PATCH 092/175] Add template to matrix --- .azure/pipelines.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 87150d0796..40fa5f7fc6 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -9,22 +9,27 @@ strategy: platform: 'ubuntu' python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + install_template: templates/install_bash.yml linux-py39: platform: 'ubuntu' python.version: '3.9' conda.packages: 'gmsh' + install_template: templates/install_bash.yml macos-py27: platform: 'macos' python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + install_template: templates/install_bash.yml macos-py39: platform: 'macos' python.version: '3.9' conda.packages: 'gmsh' + install_template: templates/install_bash.yml windows-py39: platform: 'windows' python.version: '3.9' conda.packages: 'gmsh' + install_template: templates/install_doze.yml pool: vmImage: $(platform)-latest @@ -35,21 +40,11 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: -- $[ if or(eq(platform, 'macos'), eq(platform, 'ubuntu')) ]: - - template: templates/install_bash.yml +- template: $(install_template) - bash: echo $(platform) displayName: Echo 1a -- bash: echo $(platform) $[ eq('$(platform)', 'macos') ] - displayName: Echo 2a - -- bash: echo $(platform) $[ eq('$(platform)', 'ubuntu') ] - displayName: Echo 3a - -- bash: echo $(platform) $[ or(eq('$(platform)', 'macos'), eq('$(platform)', 'ubuntu')) ] - displayName: Echo 4a - - template: templates/install.yml parameters: platform: $(platform) From 010ac97449921b71057418a10bb0f5288cdd9003 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:38:46 -0400 Subject: [PATCH 093/175] Replicate what's in documentation --- .azure/pipelines.yml | 11 +---------- .azure/templates/install.yml | 12 ++---------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 40fa5f7fc6..a3ebced724 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -9,27 +9,22 @@ strategy: platform: 'ubuntu' python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - install_template: templates/install_bash.yml linux-py39: platform: 'ubuntu' python.version: '3.9' conda.packages: 'gmsh' - install_template: templates/install_bash.yml macos-py27: platform: 'macos' python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - install_template: templates/install_bash.yml macos-py39: platform: 'macos' python.version: '3.9' conda.packages: 'gmsh' - install_template: templates/install_bash.yml windows-py39: platform: 'windows' python.version: '3.9' conda.packages: 'gmsh' - install_template: templates/install_doze.yml pool: vmImage: $(platform)-latest @@ -40,16 +35,12 @@ variables: # isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: -- template: $(install_template) - -- bash: echo $(platform) - displayName: Echo 1a - - template: templates/install.yml parameters: platform: $(platform) python.version: $(python.version) conda.packages: $(conda.packages) + experimentalTemplate: true - bash: | source activate myEnvironment diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 0237acd7f4..9cba701619 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -2,19 +2,11 @@ parameters: platform: '' python.version: 3.9 conda.packages: '' + experimentalTemplate: false steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'macos') }} - displayName: Echo 2 - - - bash: echo ${{ parameters.platform }} ${{ eq(parameters.platform, 'ubuntu') }} - displayName: Echo 3 - - - bash: echo ${{ parameters.platform }} ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} - displayName: Echo 4 - - - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: + - ${{ if eq(parameters.experimentalTemplate, true) }}: - template: install_bash.yml From b983bdcfa93af065ceafd96377ef7c3851f7cda8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:43:25 -0400 Subject: [PATCH 094/175] Make conditional --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index a3ebced724..24e1422339 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -40,7 +40,7 @@ steps: platform: $(platform) python.version: $(python.version) conda.packages: $(conda.packages) - experimentalTemplate: true + experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - bash: | source activate myEnvironment From 523ee94799dc71f66dde6cf3ebbbdbe6b3fa185e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:49:54 -0400 Subject: [PATCH 095/175] Try try again --- .azure/pipelines.yml | 4 ++-- .azure/templates/install.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 24e1422339..9e869ae89b 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -37,10 +37,10 @@ variables: steps: - template: templates/install.yml parameters: - platform: $(platform) + platform: '$(platform)' python.version: $(python.version) conda.packages: $(conda.packages) - experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] +# experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - bash: | source activate myEnvironment diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 9cba701619..4976ca4958 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -8,5 +8,5 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - ${{ if eq(parameters.experimentalTemplate, true) }}: + - ${{ or(eq(parameters.platform, 'macos'), eq(parameters., 'ubuntu')) }}: - template: install_bash.yml From 1ef946c5e205461bd5363bc52f09656ed8460ddb Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:51:17 -0400 Subject: [PATCH 096/175] Fix typo --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 4976ca4958..eed986e9c8 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -8,5 +8,5 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - ${{ or(eq(parameters.platform, 'macos'), eq(parameters., 'ubuntu')) }}: + - ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From e0c3de9e387298799c93f23b66b4dc1f53fff34e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 26 Sep 2021 23:53:06 -0400 Subject: [PATCH 097/175] Add diagnostics --- .azure/templates/install.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index eed986e9c8..9c64b16d20 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -8,5 +8,14 @@ steps: - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: + - bash: echo ${{ eq(parameters.platform, 'macos') }} + displayName: Echo 2 + + - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} + displayName: Echo 3 + + - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + displayName: Echo 4 + + - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From 5370a6477c3b6cd7ce114b9b3cbaaf228a1b954d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 06:55:05 -0400 Subject: [PATCH 098/175] Introduce bash boolean --- .azure/pipelines.yml | 6 ++++++ .azure/templates/install.yml | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 9e869ae89b..8671ff6bf9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -9,22 +9,27 @@ strategy: platform: 'ubuntu' python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + useBash: true linux-py39: platform: 'ubuntu' python.version: '3.9' conda.packages: 'gmsh' + useBash: true macos-py27: platform: 'macos' python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + useBash: true macos-py39: platform: 'macos' python.version: '3.9' conda.packages: 'gmsh' + useBash: true windows-py39: platform: 'windows' python.version: '3.9' conda.packages: 'gmsh' + useBash: false pool: vmImage: $(platform)-latest @@ -40,6 +45,7 @@ steps: platform: '$(platform)' python.version: $(python.version) conda.packages: $(conda.packages) + useBash: $(useBash) # experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - bash: | diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 9c64b16d20..0e0e14e821 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -3,6 +3,7 @@ parameters: python.version: 3.9 conda.packages: '' experimentalTemplate: false + useBash: false steps: - bash: echo ${{ parameters.platform }} @@ -17,5 +18,5 @@ steps: - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} displayName: Echo 4 - - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: + - ${{ if eq(parameters.useBash, true) }}: - template: install_bash.yml From 79482ff0c3e4b5917ae7e445f079428789eb3974 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 06:58:00 -0400 Subject: [PATCH 099/175] Spell out variable --- .azure/templates/install.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 0e0e14e821..047bb88e63 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -3,7 +3,10 @@ parameters: python.version: 3.9 conda.packages: '' experimentalTemplate: false - useBash: false + - name: useBash + displayName: 'Use Bash shell?' + type: boolean + default: false steps: - bash: echo ${{ parameters.platform }} From c91ed7c1c3c7549372bb2dc1106b6017e5c33f16 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 06:59:36 -0400 Subject: [PATCH 100/175] WTF is the syntax? --- .azure/templates/install.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 047bb88e63..0e4417f7e2 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,8 +1,8 @@ parameters: - platform: '' - python.version: 3.9 - conda.packages: '' - experimentalTemplate: false + - platform: '' + - python.version: 3.9 + - conda.packages: '' + - experimentalTemplate: false - name: useBash displayName: 'Use Bash shell?' type: boolean From 7dc2e61580607dfc74367eeaab3cbe55bc7f6860 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:02:09 -0400 Subject: [PATCH 101/175] Spell out all parameters --- .azure/templates/install.yml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 0e4417f7e2..f9e706aad8 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,12 +1,17 @@ parameters: - - platform: '' - - python.version: 3.9 - - conda.packages: '' - - experimentalTemplate: false - - name: useBash - displayName: 'Use Bash shell?' - type: boolean - default: false +- name: platform + type: str + default: '' +- name: python.version + type: str + default: 3.9 +- name: conda.packages + type: str + default: '' +- name: useBash + displayName: 'Use Bash shell?' + type: boolean + default: false steps: - bash: echo ${{ parameters.platform }} From 34202c85cdd250c56979ea47e1ae6d3b669335f4 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:05:51 -0400 Subject: [PATCH 102/175] Why is there no table of types!? --- .azure/templates/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index f9e706aad8..bd27b7bca1 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,12 +1,12 @@ parameters: - name: platform - type: str + type: string default: '' - name: python.version - type: str + type: string default: 3.9 - name: conda.packages - type: str + type: string default: '' - name: useBash displayName: 'Use Bash shell?' From ca9aae8b4561c03663da7e3a9159c7db1cbbb8b2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:09:25 -0400 Subject: [PATCH 103/175] Stumbling around in the dark --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index bd27b7bca1..1636389d90 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -26,5 +26,5 @@ steps: - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} displayName: Echo 4 - - ${{ if eq(parameters.useBash, true) }}: + - ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} - template: install_bash.yml From ee5ce50435a2038a7d87007337e06e4397a68640 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:11:43 -0400 Subject: [PATCH 104/175] Fix typo --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 1636389d90..738940f42b 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -26,5 +26,5 @@ steps: - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} displayName: Echo 4 - - ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + - ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From ac9ecd0bec0848e981591ba3fd2cebe0ab9a28a3 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:12:32 -0400 Subject: [PATCH 105/175] Don't useBash --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 8671ff6bf9..b36d47952d 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -45,7 +45,7 @@ steps: platform: '$(platform)' python.version: $(python.version) conda.packages: $(conda.packages) - useBash: $(useBash) +# useBash: $(useBash) # experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - bash: | From 3e1ca655c5beceb0762b2ad55da5208d34510f80 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:21:39 -0400 Subject: [PATCH 106/175] Change parameters to variables https://developercommunity.visualstudio.com/t/matrix-variable-that-is-passed-to-a-template-as-a/1184356 --- .azure/templates/install.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 738940f42b..2c444289f6 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -14,17 +14,17 @@ parameters: default: false steps: - - bash: echo ${{ parameters.platform }} + - bash: echo ${{ variables.platform }} displayName: Echo 1 - - bash: echo ${{ eq(parameters.platform, 'macos') }} + - bash: echo ${{ eq(variables.platform, 'macos') }} displayName: Echo 2 - - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} + - bash: echo ${{ eq(variables.platform, 'ubuntu') }} displayName: Echo 3 - - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + - bash: echo ${{ or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }} displayName: Echo 4 - - ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: + - ${{ if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }}: - template: install_bash.yml From d2f5fbf9303b2463f2f1b5378420b112a8bf07ac Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:25:23 -0400 Subject: [PATCH 107/175] Take out of squigglies --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 2c444289f6..456e674837 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -26,5 +26,5 @@ steps: - bash: echo ${{ or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }} displayName: Echo 4 - - ${{ if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }}: + - if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')): - template: install_bash.yml From 09b78d3168b90dc9c0188dadb2b4cf8e5194e6dc Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:30:07 -0400 Subject: [PATCH 108/175] Try something else --- .azure/pipelines.yml | 12 ++++++------ .azure/templates/install.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index b36d47952d..7bcfaa9887 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -6,27 +6,27 @@ strategy: matrix: linux-py27: - platform: 'ubuntu' + platform: ubuntu python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' useBash: true linux-py39: - platform: 'ubuntu' + platform: ubuntu python.version: '3.9' conda.packages: 'gmsh' useBash: true macos-py27: - platform: 'macos' + platform: macos python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' useBash: true macos-py39: - platform: 'macos' + platform: macos python.version: '3.9' conda.packages: 'gmsh' useBash: true windows-py39: - platform: 'windows' + platform: windows python.version: '3.9' conda.packages: 'gmsh' useBash: false @@ -42,7 +42,7 @@ variables: steps: - template: templates/install.yml parameters: - platform: '$(platform)' + platform: variables.platform python.version: $(python.version) conda.packages: $(conda.packages) # useBash: $(useBash) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 456e674837..3de516430f 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -26,5 +26,5 @@ steps: - bash: echo ${{ or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }} displayName: Echo 4 - - if or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')): + - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - template: install_bash.yml From a01fce146033dc08d8c1590defa876acf84488bd Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:31:55 -0400 Subject: [PATCH 109/175] Echo the right things --- .azure/templates/install.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 3de516430f..ae2374745a 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -14,16 +14,16 @@ parameters: default: false steps: - - bash: echo ${{ variables.platform }} + - bash: echo ${{ parameters.platform }} displayName: Echo 1 - - bash: echo ${{ eq(variables.platform, 'macos') }} + - bash: echo ${{ eq(parameters.platform, 'macos') }} displayName: Echo 2 - - bash: echo ${{ eq(variables.platform, 'ubuntu') }} + - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} displayName: Echo 3 - - bash: echo ${{ or(eq(variables.platform, 'macos'), eq(variables.platform, 'ubuntu')) }} + - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} displayName: Echo 4 - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: From 3e3bdbf4da4555b450354c21cbc7ad8c0905b8c8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:37:54 -0400 Subject: [PATCH 110/175] Check Microsoft lies https://developercommunity.visualstudio.com/t/matrix-variable-that-is-passed-to-a-template-as-a/1184356 --- .azure/pipelines.yml | 61 ++++++------------------------------ .azure/templates/install.yml | 45 ++++++++++++-------------- 2 files changed, 30 insertions(+), 76 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 7bcfaa9887..6013b4e75b 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -1,55 +1,14 @@ -# Conda package -# Create and test a Python package on multiple Python versions. -# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/anaconda - +pool: { vmImage: ubuntu-latest } strategy: matrix: - linux-py27: - platform: ubuntu - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - useBash: true - linux-py39: - platform: ubuntu - python.version: '3.9' - conda.packages: 'gmsh' - useBash: true - macos-py27: - platform: macos - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - useBash: true - macos-py39: - platform: macos - python.version: '3.9' - conda.packages: 'gmsh' - useBash: true - windows-py39: - platform: windows - python.version: '3.9' - conda.packages: 'gmsh' - useBash: false - -pool: - vmImage: $(platform)-latest - -variables: - system.debug: true - system.log: true -# isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - + foo: + VAR: foo + bar: + VAR: bar steps: -- template: templates/install.yml +- bash: echo $(VAR) + displayName: value from main file +- template: install.yml parameters: - platform: variables.platform - python.version: $(python.version) - conda.packages: $(conda.packages) -# useBash: $(useBash) -# experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - -- bash: | - source activate myEnvironment - python setup.py egg_info - python setup.py test --deprecation-errors - displayName: test + VAL_AS_MACRO: $(VAR) + VAL_AS_VARIABLE_DOT: variables.VAR diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index ae2374745a..a8fd457cc6 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,30 +1,25 @@ parameters: -- name: platform +- name: VAL_AS_MACRO type: string - default: '' -- name: python.version + default: eemmppttyy +- name: VAL_AS_VARIABLE_DOT type: string - default: 3.9 -- name: conda.packages - type: string - default: '' -- name: useBash - displayName: 'Use Bash shell?' - type: boolean - default: false + default: eemmppttyy steps: - - bash: echo ${{ parameters.platform }} - displayName: Echo 1 - - - bash: echo ${{ eq(parameters.platform, 'macos') }} - displayName: Echo 2 - - - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} - displayName: Echo 3 - - - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} - displayName: Echo 4 - - - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - - template: install_bash.yml +- bash: echo $(VAR) + displayName: value from template file as a variable +- bash: echo ${{ parameters.VAL_AS_MACRO }} + displayName: value from template file as an expression with macro syntax +- bash: echo ${{ parameters.VAL_AS_VARIABLE_DOT }} + displayName: value from template file as an expression with "variables." syntax +- bash: echo Yup + displayName: conditional on variable + condition: eq(variables.VAR, 'foo') +- bash: echo Yup + displayName: conditional on parameter with "variables." syntax + condition: eq(${{ parameters.VAL_AS_VARIABLE_DOT }}, 'foo') +# this next one would fail to compile +# - bash: echo NOPE +# displayName: conditional on parameter as macro syntax +# condition: eq(${{ parameters.VAL_AS_MACRO }}, 'foo') \ No newline at end of file From 4513590a816ce4914fffafa6687e3c9d520914d4 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:38:50 -0400 Subject: [PATCH 111/175] Fix typo --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 6013b4e75b..511b296edf 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -8,7 +8,7 @@ strategy: steps: - bash: echo $(VAR) displayName: value from main file -- template: install.yml +- template: templates/install.yml parameters: VAL_AS_MACRO: $(VAR) VAL_AS_VARIABLE_DOT: variables.VAR From 25150c5048f4153c8bc64c963fef989bd58a741e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:46:42 -0400 Subject: [PATCH 112/175] Revert "Fix typo" This reverts commit 4513590a816ce4914fffafa6687e3c9d520914d4. --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 511b296edf..6013b4e75b 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -8,7 +8,7 @@ strategy: steps: - bash: echo $(VAR) displayName: value from main file -- template: templates/install.yml +- template: install.yml parameters: VAL_AS_MACRO: $(VAR) VAL_AS_VARIABLE_DOT: variables.VAR From 4bda7901edc0cd4b15a4cad3f83e59705d958ffa Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:47:23 -0400 Subject: [PATCH 113/175] Revert "Check Microsoft lies" This reverts commit 3e3bdbf4da4555b450354c21cbc7ad8c0905b8c8. --- .azure/pipelines.yml | 61 ++++++++++++++++++++++++++++++------ .azure/templates/install.yml | 45 ++++++++++++++------------ 2 files changed, 76 insertions(+), 30 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 6013b4e75b..7bcfaa9887 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -1,14 +1,55 @@ -pool: { vmImage: ubuntu-latest } +# Conda package +# Create and test a Python package on multiple Python versions. +# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: +# https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/anaconda + strategy: matrix: - foo: - VAR: foo - bar: - VAR: bar + linux-py27: + platform: ubuntu + python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + useBash: true + linux-py39: + platform: ubuntu + python.version: '3.9' + conda.packages: 'gmsh' + useBash: true + macos-py27: + platform: macos + python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + useBash: true + macos-py39: + platform: macos + python.version: '3.9' + conda.packages: 'gmsh' + useBash: true + windows-py39: + platform: windows + python.version: '3.9' + conda.packages: 'gmsh' + useBash: false + +pool: + vmImage: $(platform)-latest + +variables: + system.debug: true + system.log: true +# isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] + steps: -- bash: echo $(VAR) - displayName: value from main file -- template: install.yml +- template: templates/install.yml parameters: - VAL_AS_MACRO: $(VAR) - VAL_AS_VARIABLE_DOT: variables.VAR + platform: variables.platform + python.version: $(python.version) + conda.packages: $(conda.packages) +# useBash: $(useBash) +# experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] + +- bash: | + source activate myEnvironment + python setup.py egg_info + python setup.py test --deprecation-errors + displayName: test diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index a8fd457cc6..ae2374745a 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,25 +1,30 @@ parameters: -- name: VAL_AS_MACRO +- name: platform type: string - default: eemmppttyy -- name: VAL_AS_VARIABLE_DOT + default: '' +- name: python.version type: string - default: eemmppttyy + default: 3.9 +- name: conda.packages + type: string + default: '' +- name: useBash + displayName: 'Use Bash shell?' + type: boolean + default: false steps: -- bash: echo $(VAR) - displayName: value from template file as a variable -- bash: echo ${{ parameters.VAL_AS_MACRO }} - displayName: value from template file as an expression with macro syntax -- bash: echo ${{ parameters.VAL_AS_VARIABLE_DOT }} - displayName: value from template file as an expression with "variables." syntax -- bash: echo Yup - displayName: conditional on variable - condition: eq(variables.VAR, 'foo') -- bash: echo Yup - displayName: conditional on parameter with "variables." syntax - condition: eq(${{ parameters.VAL_AS_VARIABLE_DOT }}, 'foo') -# this next one would fail to compile -# - bash: echo NOPE -# displayName: conditional on parameter as macro syntax -# condition: eq(${{ parameters.VAL_AS_MACRO }}, 'foo') \ No newline at end of file + - bash: echo ${{ parameters.platform }} + displayName: Echo 1 + + - bash: echo ${{ eq(parameters.platform, 'macos') }} + displayName: Echo 2 + + - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} + displayName: Echo 3 + + - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} + displayName: Echo 4 + + - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: + - template: install_bash.yml From 8eabba861acfa00ced315305bdd737a88a443449 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 27 Sep 2021 07:50:17 -0400 Subject: [PATCH 114/175] Simplify --- .azure/pipelines.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 7bcfaa9887..d203a1ac3e 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -37,16 +37,12 @@ pool: variables: system.debug: true system.log: true -# isBash: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] steps: -- template: templates/install.yml +- template: templates/install_bash.yml parameters: - platform: variables.platform python.version: $(python.version) conda.packages: $(conda.packages) -# useBash: $(useBash) -# experimentalTemplate: $[or(eq(platform, 'macos'), eq(platform, 'ubuntu'))] - bash: | source activate myEnvironment From 5c23df0936b11f0bc27f4afa77c8fb6e4d705619 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 13:22:34 -0400 Subject: [PATCH 115/175] Change platform to image and put conditions on each step --- .azure/pipelines.yml | 15 +++++++------ .azure/templates/install.yml | 41 ++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index d203a1ac3e..2f37cf8ede 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -6,40 +6,41 @@ strategy: matrix: linux-py27: - platform: ubuntu + image: ubuntu-latest python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' useBash: true linux-py39: - platform: ubuntu + image: ubuntu-latest python.version: '3.9' conda.packages: 'gmsh' useBash: true macos-py27: - platform: macos + image: macos-latest python.version: '2.7' conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' useBash: true macos-py39: - platform: macos + image: macos-latest python.version: '3.9' conda.packages: 'gmsh' useBash: true windows-py39: - platform: windows + image: windows-latest python.version: '3.9' conda.packages: 'gmsh' useBash: false pool: - vmImage: $(platform)-latest + vmImage: $(image) variables: system.debug: true system.log: true + useBash: or(startsWith($(image), 'ubuntu'), startsWith($(image), 'macos')) steps: -- template: templates/install_bash.yml +- template: templates/install.yml parameters: python.version: $(python.version) conda.packages: $(conda.packages) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index ae2374745a..90e38e295f 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,30 +1,35 @@ parameters: -- name: platform - type: string - default: '' - name: python.version type: string default: 3.9 - name: conda.packages type: string default: '' -- name: useBash - displayName: 'Use Bash shell?' - type: boolean - default: false steps: - - bash: echo ${{ parameters.platform }} - displayName: Echo 1 - - - bash: echo ${{ eq(parameters.platform, 'macos') }} - displayName: Echo 2 + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH + condition: eq(variables.useBash, true) - - bash: echo ${{ eq(parameters.platform, 'ubuntu') }} - displayName: Echo 3 + # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ + # We need to take ownership if we want to update conda or install packages globally + - bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + condition: startsWith(variables.image, 'macos') + + - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba + displayName: Create Anaconda environment + condition: eq(variables.useBash, true) - - bash: echo ${{ or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }} - displayName: Echo 4 + - bash: | + source activate myEnvironment + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy + mamba install --quiet --yes --channel conda-forge $(conda.packages) + displayName: Install Anaconda packages + condition: eq(variables.useBash, true) - - ${{ if or(eq(parameters.platform, 'macos'), eq(parameters.platform, 'ubuntu')) }}: - - template: install_bash.yml + - bash: | + source activate myEnvironment + pip install scikit-fmm + displayName: Install pip packages + condition: eq(variables.useBash, true) From f25bc65b8ab75c7e1062afc1d722310a74ca3982 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 13:36:12 -0400 Subject: [PATCH 116/175] Try stages --- .azure/templates/install.yml | 44 +++++++++++++++++------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 90e38e295f..7029ff1e1e 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,30 +6,28 @@ parameters: type: string default: '' -steps: - - bash: echo "##vso[task.prependpath]$CONDA/bin" - displayName: Add conda to PATH - condition: eq(variables.useBash, true) +stages: + - stage: bash_install + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH - # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ - # We need to take ownership if we want to update conda or install packages globally - - bash: sudo chown -R $USER $CONDA - displayName: Take ownership of conda installation - condition: startsWith(variables.image, 'macos') - - - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba - displayName: Create Anaconda environment - condition: eq(variables.useBash, true) + # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ + # We need to take ownership if we want to update conda or install packages globally + - bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + condition: startsWith(variables.image, 'macos') + + - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba + displayName: Create Anaconda environment - - bash: | - source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy - mamba install --quiet --yes --channel conda-forge $(conda.packages) - displayName: Install Anaconda packages - condition: eq(variables.useBash, true) + - bash: | + source activate myEnvironment + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy + mamba install --quiet --yes --channel conda-forge $(conda.packages) + displayName: Install Anaconda packages - - bash: | - source activate myEnvironment - pip install scikit-fmm - displayName: Install pip packages + - bash: | + source activate myEnvironment + pip install scikit-fmm + displayName: Install pip packages condition: eq(variables.useBash, true) From 493ddd3aaeb967b25f302d6135b739d184f9cd6d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 13:50:53 -0400 Subject: [PATCH 117/175] Switch to stages and jobs --- .azure/pipelines.yml | 22 ++++++++++++---------- .azure/templates/install.yml | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 2f37cf8ede..55aee1d9ba 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -39,14 +39,16 @@ variables: system.log: true useBash: or(startsWith($(image), 'ubuntu'), startsWith($(image), 'macos')) -steps: -- template: templates/install.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) +stages: + - stage: install + - template: templates/install.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) -- bash: | - source activate myEnvironment - python setup.py egg_info - python setup.py test --deprecation-errors - displayName: test + - stage: test + - bash: | + source activate myEnvironment + python setup.py egg_info + python setup.py test --deprecation-errors + displayName: test diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 7029ff1e1e..9392bc923f 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,8 +6,8 @@ parameters: type: string default: '' -stages: - - stage: bash_install +jobs: + - job: bash_install - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH From 57bc47d4f8a5e15f4cc580712c7f83ca1a9d4a55 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 15:21:19 -0400 Subject: [PATCH 118/175] Revert "Switch to stages and jobs" This reverts commit 493ddd3aaeb967b25f302d6135b739d184f9cd6d. --- .azure/pipelines.yml | 22 ++++++++++------------ .azure/templates/install.yml | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 55aee1d9ba..2f37cf8ede 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -39,16 +39,14 @@ variables: system.log: true useBash: or(startsWith($(image), 'ubuntu'), startsWith($(image), 'macos')) -stages: - - stage: install - - template: templates/install.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) +steps: +- template: templates/install.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) - - stage: test - - bash: | - source activate myEnvironment - python setup.py egg_info - python setup.py test --deprecation-errors - displayName: test +- bash: | + source activate myEnvironment + python setup.py egg_info + python setup.py test --deprecation-errors + displayName: test diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 9392bc923f..7029ff1e1e 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,8 +6,8 @@ parameters: type: string default: '' -jobs: - - job: bash_install +stages: + - stage: bash_install - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH From b2f7a48c98e0b4c97873afd43405ec060f1d6ee0 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 15:21:34 -0400 Subject: [PATCH 119/175] Revert "Try stages" This reverts commit f25bc65b8ab75c7e1062afc1d722310a74ca3982. --- .azure/templates/install.yml | 44 +++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 7029ff1e1e..90e38e295f 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,28 +6,30 @@ parameters: type: string default: '' -stages: - - stage: bash_install - - bash: echo "##vso[task.prependpath]$CONDA/bin" - displayName: Add conda to PATH +steps: + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH + condition: eq(variables.useBash, true) - # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ - # We need to take ownership if we want to update conda or install packages globally - - bash: sudo chown -R $USER $CONDA - displayName: Take ownership of conda installation - condition: startsWith(variables.image, 'macos') - - - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba - displayName: Create Anaconda environment + # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ + # We need to take ownership if we want to update conda or install packages globally + - bash: sudo chown -R $USER $CONDA + displayName: Take ownership of conda installation + condition: startsWith(variables.image, 'macos') + + - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba + displayName: Create Anaconda environment + condition: eq(variables.useBash, true) - - bash: | - source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy - mamba install --quiet --yes --channel conda-forge $(conda.packages) - displayName: Install Anaconda packages + - bash: | + source activate myEnvironment + mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy + mamba install --quiet --yes --channel conda-forge $(conda.packages) + displayName: Install Anaconda packages + condition: eq(variables.useBash, true) - - bash: | - source activate myEnvironment - pip install scikit-fmm - displayName: Install pip packages + - bash: | + source activate myEnvironment + pip install scikit-fmm + displayName: Install pip packages condition: eq(variables.useBash, true) From b8e4228101b5aa09e237dc63238f7990b55ca9d2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 15:23:13 -0400 Subject: [PATCH 120/175] Use bash for everybody! --- .azure/templates/install.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 90e38e295f..6d762161bc 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -9,7 +9,7 @@ parameters: steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH - condition: eq(variables.useBash, true) +# condition: eq(variables.useBash, true) # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ # We need to take ownership if we want to update conda or install packages globally @@ -19,17 +19,17 @@ steps: - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment - condition: eq(variables.useBash, true) +# condition: eq(variables.useBash, true) - bash: | source activate myEnvironment mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy mamba install --quiet --yes --channel conda-forge $(conda.packages) displayName: Install Anaconda packages - condition: eq(variables.useBash, true) +# condition: eq(variables.useBash, true) - bash: | source activate myEnvironment pip install scikit-fmm displayName: Install pip packages - condition: eq(variables.useBash, true) +# condition: eq(variables.useBash, true) From 027e4baa70f1a454df458bc0ac2df887037fcb55 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 15:27:56 -0400 Subject: [PATCH 121/175] Distinguish conda path between unix and windows --- .azure/templates/install.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 6d762161bc..4562b379be 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -9,7 +9,11 @@ parameters: steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH -# condition: eq(variables.useBash, true) + condition: or(startsWith(variables.image, 'macos'), startsWith(variables.image, 'ubuntu')) + + - bash: echo "##vso[task.prependpath]$CONDA/Scripts" + displayName: Add conda to PATH + condition: startsWith(variables.image, 'windows') # On Hosted macOS, the agent user doesn't have ownership of Miniconda's installation directory/ # We need to take ownership if we want to update conda or install packages globally From eaf86e01d35cd0160521ee043b04ec7c5fd4ea44 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 16:28:27 -0400 Subject: [PATCH 122/175] Configure conda --- .azure/templates/install.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 4562b379be..fb9104b860 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -21,19 +21,19 @@ steps: displayName: Take ownership of conda installation condition: startsWith(variables.image, 'macos') - - bash: conda create --yes --quiet --name myEnvironment --channel conda-forge mamba + - bash: | + conda config --set always_yes yes --set changeps1 no + conda config --remove channels defaults + conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment -# condition: eq(variables.useBash, true) - bash: | source activate myEnvironment - mamba install --quiet --yes --channel conda-forge --only-deps python=$(python.version) fipy - mamba install --quiet --yes --channel conda-forge $(conda.packages) + mamba install --quiet --channel conda-forge --only-deps python=$(python.version) fipy + mamba install --quiet --channel conda-forge $(conda.packages) displayName: Install Anaconda packages -# condition: eq(variables.useBash, true) - bash: | source activate myEnvironment pip install scikit-fmm displayName: Install pip packages -# condition: eq(variables.useBash, true) From 38dc345529c76cad51a0b90a5ae1362a9bcd935b Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 16:28:41 -0400 Subject: [PATCH 123/175] Use jobs --- .azure/pipelines.yml | 80 +++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 2f37cf8ede..18f78fe71d 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -3,50 +3,46 @@ # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: # https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/anaconda -strategy: - matrix: - linux-py27: - image: ubuntu-latest - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - useBash: true - linux-py39: - image: ubuntu-latest - python.version: '3.9' - conda.packages: 'gmsh' - useBash: true - macos-py27: - image: macos-latest - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' - useBash: true - macos-py39: - image: macos-latest - python.version: '3.9' - conda.packages: 'gmsh' - useBash: true - windows-py39: - image: windows-latest - python.version: '3.9' - conda.packages: 'gmsh' - useBash: false - -pool: - vmImage: $(image) - variables: system.debug: true system.log: true - useBash: or(startsWith($(image), 'ubuntu'), startsWith($(image), 'macos')) -steps: -- template: templates/install.yml - parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) +jobs: + - job: Test + strategy: + matrix: + linux-py27: + image: ubuntu-latest + python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + linux-py39: + image: ubuntu-latest + python.version: '3.9' + conda.packages: 'gmsh' + macos-py27: + image: macos-latest + python.version: '2.7' + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + macos-py39: + image: macos-latest + python.version: '3.9' + conda.packages: 'gmsh' + windows-py39: + image: windows-latest + python.version: '3.9' + conda.packages: 'gmsh' + + pool: + vmImage: $(image) + + steps: + - template: templates/install.yml + parameters: + python.version: $(python.version) + conda.packages: $(conda.packages) -- bash: | - source activate myEnvironment - python setup.py egg_info - python setup.py test --deprecation-errors - displayName: test + - bash: | + source activate myEnvironment + python setup.py install + python setup.py test --deprecation-errors + displayName: test From a13cb17693ebbdfa9bd94af653583ae5e0893bdf Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 16:33:26 -0400 Subject: [PATCH 124/175] Strip quotes from matrix values --- .azure/pipelines.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 18f78fe71d..ae5e0340a9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -13,24 +13,24 @@ jobs: matrix: linux-py27: image: ubuntu-latest - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + python.version: 2.7 + conda.packages: "traitsui<7.0.0" "gmsh<4.0" linux-py39: image: ubuntu-latest - python.version: '3.9' - conda.packages: 'gmsh' + python.version: 3.9 + conda.packages: gmsh macos-py27: image: macos-latest - python.version: '2.7' - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + python.version: 2.7 + conda.packages: "traitsui<7.0.0" "gmsh<4.0" macos-py39: image: macos-latest - python.version: '3.9' - conda.packages: 'gmsh' + python.version: 3.9 + conda.packages: gmsh windows-py39: image: windows-latest - python.version: '3.9' - conda.packages: 'gmsh' + python.version: 3.9 + conda.packages: gmsh pool: vmImage: $(image) From 107a0b633e6baadfb657c3dd5d65bd5eef48ebc4 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 16:34:26 -0400 Subject: [PATCH 125/175] Re-add some quotes --- .azure/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index ae5e0340a9..f560bf7e25 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -14,7 +14,7 @@ jobs: linux-py27: image: ubuntu-latest python.version: 2.7 - conda.packages: "traitsui<7.0.0" "gmsh<4.0" + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' linux-py39: image: ubuntu-latest python.version: 3.9 @@ -22,7 +22,7 @@ jobs: macos-py27: image: macos-latest python.version: 2.7 - conda.packages: "traitsui<7.0.0" "gmsh<4.0" + conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' macos-py39: image: macos-latest python.version: 3.9 From e5289b345fdc9876ba66b6ac304e900186bd5137 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 16:38:01 -0400 Subject: [PATCH 126/175] Introduce FIPY_SOLVERS --- .azure/pipelines.yml | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f560bf7e25..dffd537c6a 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -15,22 +15,47 @@ jobs: image: ubuntu-latest python.version: 2.7 conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + FIPY_SOLVERS: pysparse linux-py39: image: ubuntu-latest python.version: 3.9 conda.packages: gmsh + FIPY_SOLVERS: petsc + linux-py39: + image: ubuntu-latest + python.version: 3.9 + conda.packages: gmsh + FIPY_SOLVERS: scipy + linux-py39: + image: ubuntu-latest + python.version: 3.9 + conda.packages: gmsh + FIPY_SOLVERS: trilinos macos-py27: image: macos-latest python.version: 2.7 conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + FIPY_SOLVERS: pysparse + macos-py39: + image: macos-latest + python.version: 3.9 + conda.packages: gmsh + FIPY_SOLVERS: petsc + macos-py39: + image: macos-latest + python.version: 3.9 + conda.packages: gmsh + FIPY_SOLVERS: scipy macos-py39: image: macos-latest python.version: 3.9 conda.packages: gmsh + FIPY_SOLVERS: trilinos windows-py39: image: windows-latest python.version: 3.9 conda.packages: gmsh + FIPY_SOLVERS: scipy pool: vmImage: $(image) @@ -45,4 +70,6 @@ jobs: source activate myEnvironment python setup.py install python setup.py test --deprecation-errors - displayName: test + env: + FIPY_SOLVERS: $(FIPY_SOLVERS) + displayName: Test From 22009e6e53ce8758e6b128b5e2b0ebfc454d16a6 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 16:39:37 -0400 Subject: [PATCH 127/175] Add solver to matrix names --- .azure/pipelines.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index dffd537c6a..cb6d1c165b 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -11,47 +11,47 @@ jobs: - job: Test strategy: matrix: - linux-py27: + linux-py27-pysparse: image: ubuntu-latest python.version: 2.7 conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' FIPY_SOLVERS: pysparse - linux-py39: + linux-py39-petsc: image: ubuntu-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: petsc - linux-py39: + linux-py39-scipy: image: ubuntu-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: scipy - linux-py39: + linux-py39-trilinos: image: ubuntu-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: trilinos - macos-py27: + macos-py27-pysparse: image: macos-latest python.version: 2.7 conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' FIPY_SOLVERS: pysparse - macos-py39: + macos-py39-petsc: image: macos-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: petsc - macos-py39: + macos-py39-scipy: image: macos-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: scipy - macos-py39: + macos-py39-trilinos: image: macos-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: trilinos - windows-py39: + windows-py39-scipy: image: windows-latest python.version: 3.9 conda.packages: gmsh From 0a91d4374b67b0b49b82053d6e2e1637144b5b2c Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 17:08:27 -0400 Subject: [PATCH 128/175] Introduce parallel --- .azure/pipelines.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index cb6d1c165b..c67895d3d0 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -21,6 +21,12 @@ jobs: python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: petsc + linux-py39-petsc-parallel: + image: ubuntu-latest + python.version: 3.9 + conda.packages: gmsh + FIPY_SOLVERS: petsc + MPIRUN: 'mpirun -np 2' linux-py39-scipy: image: ubuntu-latest python.version: 3.9 @@ -29,7 +35,7 @@ jobs: linux-py39-trilinos: image: ubuntu-latest python.version: 3.9 - conda.packages: gmsh + conda.packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos macos-py27-pysparse: image: macos-latest @@ -41,6 +47,12 @@ jobs: python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: petsc + macos-py39-petsc-parallel: + image: macos-latest + python.version: 3.9 + conda.packages: gmsh + FIPY_SOLVERS: petsc + MPIRUN: 'mpirun -np 2' macos-py39-scipy: image: macos-latest python.version: 3.9 @@ -49,7 +61,7 @@ jobs: macos-py39-trilinos: image: macos-latest python.version: 3.9 - conda.packages: gmsh + conda.packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos windows-py39-scipy: image: windows-latest @@ -69,7 +81,8 @@ jobs: - bash: | source activate myEnvironment python setup.py install - python setup.py test --deprecation-errors + $MPIRUN python setup.py test --deprecation-errors env: FIPY_SOLVERS: $(FIPY_SOLVERS) + MPIRUN: $(MPIRUN) displayName: Test From 9a076e088b4805f1445d3874fe8e0c8af9b3074c Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 17:25:33 -0400 Subject: [PATCH 129/175] Define MPIRUN for all variants --- .azure/pipelines.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index c67895d3d0..05ca6aba8c 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -16,11 +16,13 @@ jobs: python.version: 2.7 conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' FIPY_SOLVERS: pysparse + MPIRUN: linux-py39-petsc: image: ubuntu-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: petsc + MPIRUN: linux-py39-petsc-parallel: image: ubuntu-latest python.version: 3.9 @@ -32,21 +34,25 @@ jobs: python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: scipy + MPIRUN: linux-py39-trilinos: image: ubuntu-latest python.version: 3.9 conda.packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos + MPIRUN: macos-py27-pysparse: image: macos-latest python.version: 2.7 conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' FIPY_SOLVERS: pysparse + MPIRUN: macos-py39-petsc: image: macos-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: petsc + MPIRUN: macos-py39-petsc-parallel: image: macos-latest python.version: 3.9 @@ -58,16 +64,19 @@ jobs: python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: scipy + MPIRUN: macos-py39-trilinos: image: macos-latest python.version: 3.9 conda.packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos + MPIRUN: windows-py39-scipy: image: windows-latest python.version: 3.9 conda.packages: gmsh FIPY_SOLVERS: scipy + MPIRUN: pool: vmImage: $(image) From e4be57b22413a33ca2aa96ca8c1c28503ce95702 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 17:34:20 -0400 Subject: [PATCH 130/175] Add HTML doc build --- .azure/pipelines.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 05ca6aba8c..b64e89253c 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -87,6 +87,10 @@ jobs: python.version: $(python.version) conda.packages: $(conda.packages) + - bash: | + conda env export + displayName: Environment + - bash: | source activate myEnvironment python setup.py install @@ -95,3 +99,19 @@ jobs: FIPY_SOLVERS: $(FIPY_SOLVERS) MPIRUN: $(MPIRUN) displayName: Test + + - job: Docs + pool: + vmImage: $(image) + + steps: + - template: templates/install.yml + parameters: + python.version: 3.9 + conda.packages: + + - bash: | + export ETS_TOOLKIT=null + python setup.py build_docs --html + tar -czf html.tar.gz -C documentation/_build html + displayName: HTML From 12b3951e7acf4dd3b41853200eedacf6db25cc66 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 17:38:10 -0400 Subject: [PATCH 131/175] Specify image --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index b64e89253c..3f474bcd1e 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -102,7 +102,7 @@ jobs: - job: Docs pool: - vmImage: $(image) + vmImage: ubuntu-latest steps: - template: templates/install.yml From b32b281615c230b31f164dcb4c435bc923324719 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 17:39:47 -0400 Subject: [PATCH 132/175] Specify environment to export --- .azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 3f474bcd1e..8891488b05 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -88,7 +88,7 @@ jobs: conda.packages: $(conda.packages) - bash: | - conda env export + conda env export --name myEnvironment displayName: Environment - bash: | From 15e18311bca6bf2c29328ce31c1741c4836f8a15 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 17:44:00 -0400 Subject: [PATCH 133/175] Specify image variable --- .azure/pipelines.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 8891488b05..2b4af19910 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -101,6 +101,9 @@ jobs: displayName: Test - job: Docs + variables: + image: ubuntu-latest + pool: vmImage: ubuntu-latest From 0b6a4400d34f859910dedd93cfcb90df49556aba Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:00:13 -0400 Subject: [PATCH 134/175] Change variables to parameters --- .azure/templates/install.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index fb9104b860..6aa1585aa5 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -29,8 +29,8 @@ steps: - bash: | source activate myEnvironment - mamba install --quiet --channel conda-forge --only-deps python=$(python.version) fipy - mamba install --quiet --channel conda-forge $(conda.packages) + mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python.version }} fipy + mamba install --quiet --channel conda-forge ${{ parameters.conda.packages }} displayName: Install Anaconda packages - bash: | From b3f01dae3cf14da7e675e35366920457a0615ae8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:02:31 -0400 Subject: [PATCH 135/175] De-dot parameter names --- .azure/pipelines.yml | 52 ++++++++++++++++++------------------ .azure/templates/install.yml | 8 +++--- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 2b4af19910..4363039eae 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -13,68 +13,68 @@ jobs: matrix: linux-py27-pysparse: image: ubuntu-latest - python.version: 2.7 - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + python_version: 2.7 + conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' FIPY_SOLVERS: pysparse MPIRUN: linux-py39-petsc: image: ubuntu-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: petsc MPIRUN: linux-py39-petsc-parallel: image: ubuntu-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: petsc MPIRUN: 'mpirun -np 2' linux-py39-scipy: image: ubuntu-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: scipy MPIRUN: linux-py39-trilinos: image: ubuntu-latest - python.version: 3.9 - conda.packages: 'gmsh pytrilinos' + python_version: 3.9 + conda_packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos MPIRUN: macos-py27-pysparse: image: macos-latest - python.version: 2.7 - conda.packages: '"traitsui<7.0.0" "gmsh<4.0"' + python_version: 2.7 + conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' FIPY_SOLVERS: pysparse MPIRUN: macos-py39-petsc: image: macos-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: petsc MPIRUN: macos-py39-petsc-parallel: image: macos-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: petsc MPIRUN: 'mpirun -np 2' macos-py39-scipy: image: macos-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: scipy MPIRUN: macos-py39-trilinos: image: macos-latest - python.version: 3.9 - conda.packages: 'gmsh pytrilinos' + python_version: 3.9 + conda_packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos MPIRUN: windows-py39-scipy: image: windows-latest - python.version: 3.9 - conda.packages: gmsh + python_version: 3.9 + conda_packages: gmsh FIPY_SOLVERS: scipy MPIRUN: @@ -84,8 +84,8 @@ jobs: steps: - template: templates/install.yml parameters: - python.version: $(python.version) - conda.packages: $(conda.packages) + python_version: $(python_version) + conda_packages: $(conda_packages) - bash: | conda env export --name myEnvironment @@ -110,8 +110,8 @@ jobs: steps: - template: templates/install.yml parameters: - python.version: 3.9 - conda.packages: + python_version: 3.9 + conda_packages: - bash: | export ETS_TOOLKIT=null diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 6aa1585aa5..c1f8ab83e9 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -1,8 +1,8 @@ parameters: -- name: python.version +- name: python_version type: string default: 3.9 -- name: conda.packages +- name: conda_packages type: string default: '' @@ -29,8 +29,8 @@ steps: - bash: | source activate myEnvironment - mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python.version }} fipy - mamba install --quiet --channel conda-forge ${{ parameters.conda.packages }} + mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy + mamba install --quiet --channel conda-forge ${{ parameters.conda_packages }} displayName: Install Anaconda packages - bash: | From ed011248d6a231b05f2fa19e96619358d14cc5bf Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:06:47 -0400 Subject: [PATCH 136/175] Combine mamba installs --- .azure/templates/install.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index c1f8ab83e9..8ba85cb155 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -29,8 +29,7 @@ steps: - bash: | source activate myEnvironment - mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy - mamba install --quiet --channel conda-forge ${{ parameters.conda_packages }} + mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy ${{ parameters.conda_packages }} displayName: Install Anaconda packages - bash: | From b71c14cf3d3c7dee84970c7ce93572be0ffd08d8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:13:17 -0400 Subject: [PATCH 137/175] Install packages needed by docs --- .azure/pipelines.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 4363039eae..bfaf52503a 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -111,7 +111,13 @@ jobs: - template: templates/install.yml parameters: python_version: 3.9 - conda_packages: + conda_packages: 'sphinx future matplotlib pandas imagemagick' + + - bash: | + source activate myEnvironment + pip install sphinxcontrib-bibtex + pip install numpydoc + displayName: Install pip packages - bash: | export ETS_TOOLKIT=null From 9db40a2b5868c7db328fbacaff5c402a5292f4ea Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:17:47 -0400 Subject: [PATCH 138/175] Activate environment --- .azure/pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index bfaf52503a..dbf21533cc 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -120,6 +120,7 @@ jobs: displayName: Install pip packages - bash: | + source activate myEnvironment export ETS_TOOLKIT=null python setup.py build_docs --html tar -czf html.tar.gz -C documentation/_build html From f4a5ad9ed8117ffd9ae2a46c3d94a5aee7b8a885 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:26:59 -0400 Subject: [PATCH 139/175] Split mamba install back into two steps --- .azure/templates/install.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 8ba85cb155..3fb1b93091 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -29,7 +29,8 @@ steps: - bash: | source activate myEnvironment - mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy ${{ parameters.conda_packages }} + mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy + mamba install --quiet --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} displayName: Install Anaconda packages - bash: | From 3b208960a3bf0572bc035db8205f88ab17f5442d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:44:59 -0400 Subject: [PATCH 140/175] Publish HTML tarball --- .azure/pipelines.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index dbf21533cc..c9cc2911e9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -125,3 +125,6 @@ jobs: python setup.py build_docs --html tar -czf html.tar.gz -C documentation/_build html displayName: HTML + + - publish: $(System.DefaultWorkingDirectory)/html.tar.gz + artifact: html.tar.gz From 08447865ba5a51af8ebba3a3d8f75c234371c983 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 18:52:19 -0400 Subject: [PATCH 141/175] Build PDF --- .azure/pipelines.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index c9cc2911e9..87d8989035 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -128,3 +128,12 @@ jobs: - publish: $(System.DefaultWorkingDirectory)/html.tar.gz artifact: html.tar.gz + + - bash: | + source activate myEnvironment + export ETS_TOOLKIT=null + python setup.py build_docs --pdf + displayName: PDF + + - publish: $(System.DefaultWorkingDirectory)/documentation/_build/latex/fipy.pdf + artifact: fipy.pdf From 10d49adaeca8c62f2190cafc08be431bd7fa1740 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 19:00:20 -0400 Subject: [PATCH 142/175] Install LaTeX --- .azure/pipelines.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 87d8989035..c90bcd9325 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -129,6 +129,16 @@ jobs: - publish: $(System.DefaultWorkingDirectory)/html.tar.gz artifact: html.tar.gz + - bash: | + apt-get --yes update + apt-get --yes install texlive-latex-base + apt-get --yes install texlive-fonts-recommended + apt-get --yes install texlive-fonts-extra + apt-get --yes install texlive-latex-extra + apt-get --yes install texlive-science + apt-get --yes install texlive-extra-utils + displayName: Install LaTeX + - bash: | source activate myEnvironment export ETS_TOOLKIT=null From b5f0f0cc8f611a75187c3d75301f16df8eceaa60 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Wed, 29 Sep 2021 19:09:08 -0400 Subject: [PATCH 143/175] sudo the things --- .azure/pipelines.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index c90bcd9325..f8fa1a4171 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -129,14 +129,17 @@ jobs: - publish: $(System.DefaultWorkingDirectory)/html.tar.gz artifact: html.tar.gz + - publish: $(System.DefaultWorkingDirectory)/documentation/_build/html + artifact: html + - bash: | - apt-get --yes update - apt-get --yes install texlive-latex-base - apt-get --yes install texlive-fonts-recommended - apt-get --yes install texlive-fonts-extra - apt-get --yes install texlive-latex-extra - apt-get --yes install texlive-science - apt-get --yes install texlive-extra-utils + sudo apt-get --yes update + sudo apt-get --yes install texlive-latex-base + sudo apt-get --yes install texlive-fonts-recommended + sudo apt-get --yes install texlive-fonts-extra + sudo apt-get --yes install texlive-latex-extra + sudo apt-get --yes install texlive-science + sudo apt-get --yes install texlive-extra-utils displayName: Install LaTeX - bash: | From 50110f2f459ec150ce3aa05c7699cfb9f381e9db Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 09:15:39 -0400 Subject: [PATCH 144/175] Try caching --- .azure/templates/install.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 3fb1b93091..547f4fc9a0 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,6 +6,9 @@ parameters: type: string default: '' +variables: + CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc + steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH @@ -21,19 +24,38 @@ steps: displayName: Take ownership of conda installation condition: startsWith(variables.image, 'macos') + - task: Cache@2 + displayName: Use cached Anaconda environment + inputs: + key: 'conda | "$(Agent.OS)" | myEnvironment.yml' + restoreKeys: | + python | "$(Agent.OS)" + python + path: $(CONDA_CACHE_DIR) + cacheHitVar: CONDA_CACHE_RESTORED + - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment + condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - bash: | source activate myEnvironment mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy mamba install --quiet --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} displayName: Install Anaconda packages + condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - bash: | source activate myEnvironment pip install scikit-fmm displayName: Install pip packages + condition: eq(variables.CONDA_CACHE_RESTORED, 'false') + + - bash: | + source activate myEnvironment + conda env export > myEnvironment.yml + displayName: Export Anaconda environment + condition: eq(variables.CONDA_CACHE_RESTORED, 'false') From 441e645495a7e55a6c4cf2ffea1c2a87de73da5b Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 09:17:06 -0400 Subject: [PATCH 145/175] Move variables from template to pipeline!? --- .azure/pipelines.yml | 1 + .azure/templates/install.yml | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f8fa1a4171..4c2c0958f4 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -6,6 +6,7 @@ variables: system.debug: true system.log: true + CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc jobs: - job: Test diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 547f4fc9a0..67322b5593 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,9 +6,6 @@ parameters: type: string default: '' -variables: - CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc - steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH From 934eeb77d23d88738b5c1b47ca11344f024da8b9 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 09:56:24 -0400 Subject: [PATCH 146/175] Initialize myEnvironment.yml --- .azure/templates/install.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 67322b5593..3335b58be6 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -11,7 +11,7 @@ steps: displayName: Add conda to PATH condition: or(startsWith(variables.image, 'macos'), startsWith(variables.image, 'ubuntu')) - - bash: echo "##vso[task.prependpath]$CONDA/Scripts" + - bash: echo "##vso[task.prependpath]$CONDA\Scripts" displayName: Add conda to PATH condition: startsWith(variables.image, 'windows') @@ -21,6 +21,10 @@ steps: displayName: Take ownership of conda installation condition: startsWith(variables.image, 'macos') + - bash: | + conda env export --name myEnvironment > myEnvironment.yml + displayName: Export Anaconda environment + - task: Cache@2 displayName: Use cached Anaconda environment inputs: @@ -52,7 +56,6 @@ steps: condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - bash: | - source activate myEnvironment - conda env export > myEnvironment.yml + conda env export --name myEnvironment > myEnvironment.yml displayName: Export Anaconda environment condition: eq(variables.CONDA_CACHE_RESTORED, 'false') From 65cc676e0dd33b2017cec4ae08184ee5010ff26b Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 10:04:43 -0400 Subject: [PATCH 147/175] Make installation a dependency --- .azure/pipelines.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 4c2c0958f4..f3286061a6 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -9,7 +9,41 @@ variables: CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc jobs: + - job: Install + strategy: + matrix: + linux-py27: + image: ubuntu-latest + python_version: 2.7 + conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' + linux-py39: + image: ubuntu-latest + python_version: 3.9 + conda_packages: 'gmsh pytrilinos' + macos-py27: + image: macos-latest + python_version: 2.7 + conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' + macos-py39: + image: macos-latest + python_version: 3.9 + conda_packages: 'gmsh pytrilinos' + windows-py39: + image: windows-latest + python_version: 3.9 + conda_packages: gmsh + + pool: + vmImage: $(image) + + steps: + - template: templates/install.yml + parameters: + python_version: $(python_version) + conda_packages: $(conda_packages) + - job: Test + dependsOn: Install strategy: matrix: linux-py27-pysparse: @@ -102,6 +136,7 @@ jobs: displayName: Test - job: Docs + dependsOn: Install variables: image: ubuntu-latest From 61c76aaffa0b6b935d3da103091ce29f383776c2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 10:14:00 -0400 Subject: [PATCH 148/175] Comment out installation configurations that block dependencies --- .azure/pipelines.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f3286061a6..3aba4f802c 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -12,26 +12,28 @@ jobs: - job: Install strategy: matrix: - linux-py27: - image: ubuntu-latest - python_version: 2.7 - conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' +# linux-py27: +# image: ubuntu-latest +# python_version: 2.7 +# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' linux-py39: image: ubuntu-latest python_version: 3.9 - conda_packages: 'gmsh pytrilinos' - macos-py27: - image: macos-latest - python_version: 2.7 - conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' + conda_packages: gmsh +# conda_packages: 'gmsh pytrilinos' +# macos-py27: +# image: macos-latest +# python_version: 2.7 +# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' macos-py39: image: macos-latest python_version: 3.9 - conda_packages: 'gmsh pytrilinos' - windows-py39: - image: windows-latest - python_version: 3.9 conda_packages: gmsh +# conda_packages: 'gmsh pytrilinos' +# windows-py39: +# image: windows-latest +# python_version: 3.9 +# conda_packages: gmsh pool: vmImage: $(image) From 7388eb1cf907fba40f9bddea98b5d8d419d4e8c0 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 10:25:52 -0400 Subject: [PATCH 149/175] Cache actual environment --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 3335b58be6..2a381c7915 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -32,7 +32,7 @@ steps: restoreKeys: | python | "$(Agent.OS)" python - path: $(CONDA_CACHE_DIR) + path: $(CONDA)/envs/myEnvironment/ cacheHitVar: CONDA_CACHE_RESTORED - bash: | From c2a59efded94d45d547d511bdcc28be0ebe9d583 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 10:44:06 -0400 Subject: [PATCH 150/175] Revert caching experiments Caching doesn't speed things up and dependencies are whack --- .azure/pipelines.yml | 38 ------------------------------------ .azure/templates/install.yml | 14 ++++++------- 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 3aba4f802c..f8fa1a4171 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -6,46 +6,9 @@ variables: system.debug: true system.log: true - CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc jobs: - - job: Install - strategy: - matrix: -# linux-py27: -# image: ubuntu-latest -# python_version: 2.7 -# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' - linux-py39: - image: ubuntu-latest - python_version: 3.9 - conda_packages: gmsh -# conda_packages: 'gmsh pytrilinos' -# macos-py27: -# image: macos-latest -# python_version: 2.7 -# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' - macos-py39: - image: macos-latest - python_version: 3.9 - conda_packages: gmsh -# conda_packages: 'gmsh pytrilinos' -# windows-py39: -# image: windows-latest -# python_version: 3.9 -# conda_packages: gmsh - - pool: - vmImage: $(image) - - steps: - - template: templates/install.yml - parameters: - python_version: $(python_version) - conda_packages: $(conda_packages) - - job: Test - dependsOn: Install strategy: matrix: linux-py27-pysparse: @@ -138,7 +101,6 @@ jobs: displayName: Test - job: Docs - dependsOn: Install variables: image: ubuntu-latest diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 2a381c7915..547f4fc9a0 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,12 +6,15 @@ parameters: type: string default: '' +variables: + CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc + steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH condition: or(startsWith(variables.image, 'macos'), startsWith(variables.image, 'ubuntu')) - - bash: echo "##vso[task.prependpath]$CONDA\Scripts" + - bash: echo "##vso[task.prependpath]$CONDA/Scripts" displayName: Add conda to PATH condition: startsWith(variables.image, 'windows') @@ -21,10 +24,6 @@ steps: displayName: Take ownership of conda installation condition: startsWith(variables.image, 'macos') - - bash: | - conda env export --name myEnvironment > myEnvironment.yml - displayName: Export Anaconda environment - - task: Cache@2 displayName: Use cached Anaconda environment inputs: @@ -32,7 +31,7 @@ steps: restoreKeys: | python | "$(Agent.OS)" python - path: $(CONDA)/envs/myEnvironment/ + path: $(CONDA_CACHE_DIR) cacheHitVar: CONDA_CACHE_RESTORED - bash: | @@ -56,6 +55,7 @@ steps: condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - bash: | - conda env export --name myEnvironment > myEnvironment.yml + source activate myEnvironment + conda env export > myEnvironment.yml displayName: Export Anaconda environment condition: eq(variables.CONDA_CACHE_RESTORED, 'false') From a6db1a82a9bbc8d48ac4aeb8f6fd3d1453c3ae02 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 10:47:05 -0400 Subject: [PATCH 151/175] Revert "Try caching" This reverts commit 50110f2f459ec150ce3aa05c7699cfb9f381e9db. --- .azure/templates/install.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 547f4fc9a0..3fb1b93091 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -6,9 +6,6 @@ parameters: type: string default: '' -variables: - CONDA_CACHE_DIR: $(Pipeline.Workspace)/.condarc - steps: - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH @@ -24,38 +21,19 @@ steps: displayName: Take ownership of conda installation condition: startsWith(variables.image, 'macos') - - task: Cache@2 - displayName: Use cached Anaconda environment - inputs: - key: 'conda | "$(Agent.OS)" | myEnvironment.yml' - restoreKeys: | - python | "$(Agent.OS)" - python - path: $(CONDA_CACHE_DIR) - cacheHitVar: CONDA_CACHE_RESTORED - - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults conda create --yes --quiet --name myEnvironment --channel conda-forge mamba displayName: Create Anaconda environment - condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - bash: | source activate myEnvironment mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy mamba install --quiet --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} displayName: Install Anaconda packages - condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - bash: | source activate myEnvironment pip install scikit-fmm displayName: Install pip packages - condition: eq(variables.CONDA_CACHE_RESTORED, 'false') - - - bash: | - source activate myEnvironment - conda env export > myEnvironment.yml - displayName: Export Anaconda environment - condition: eq(variables.CONDA_CACHE_RESTORED, 'false') From 47b69df7eb5416160a5999768e61beb723064a37 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 10:14:00 -0400 Subject: [PATCH 152/175] Make installation a dependency --- .azure/pipelines.yml | 48 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f8fa1a4171..d65b92811b 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -8,7 +8,43 @@ variables: system.log: true jobs: + - job: Install + strategy: + matrix: +# linux-py27: +# image: ubuntu-latest +# python_version: 2.7 +# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' + linux-py39: + image: ubuntu-latest + python_version: 3.9 + conda_packages: gmsh +# conda_packages: 'gmsh pytrilinos' +# macos-py27: +# image: macos-latest +# python_version: 2.7 +# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' + macos-py39: + image: macos-latest + python_version: 3.9 + conda_packages: gmsh +# conda_packages: 'gmsh pytrilinos' +# windows-py39: +# image: windows-latest +# python_version: 3.9 +# conda_packages: gmsh + + pool: + vmImage: $(image) + + steps: + - template: templates/install.yml + parameters: + python_version: $(python_version) + conda_packages: $(conda_packages) + - job: Test + dependsOn: Install strategy: matrix: linux-py27-pysparse: @@ -82,11 +118,6 @@ jobs: vmImage: $(image) steps: - - template: templates/install.yml - parameters: - python_version: $(python_version) - conda_packages: $(conda_packages) - - bash: | conda env export --name myEnvironment displayName: Environment @@ -101,6 +132,8 @@ jobs: displayName: Test - job: Docs + dependsOn: Install + variables: image: ubuntu-latest @@ -108,11 +141,6 @@ jobs: vmImage: ubuntu-latest steps: - - template: templates/install.yml - parameters: - python_version: 3.9 - conda_packages: 'sphinx future matplotlib pandas imagemagick' - - bash: | source activate myEnvironment pip install sphinxcontrib-bibtex From dc4fc2dc76a3478a7ec48f2c41eab475b80d73ae Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 11:11:51 -0400 Subject: [PATCH 153/175] Revert "Make installation a dependency" This reverts commit 47b69df7eb5416160a5999768e61beb723064a37. --- .azure/pipelines.yml | 48 +++++++++----------------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index d65b92811b..f8fa1a4171 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -8,43 +8,7 @@ variables: system.log: true jobs: - - job: Install - strategy: - matrix: -# linux-py27: -# image: ubuntu-latest -# python_version: 2.7 -# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' - linux-py39: - image: ubuntu-latest - python_version: 3.9 - conda_packages: gmsh -# conda_packages: 'gmsh pytrilinos' -# macos-py27: -# image: macos-latest -# python_version: 2.7 -# conda_packages: '"traitsui<7.0.0" "gmsh<4.0"' - macos-py39: - image: macos-latest - python_version: 3.9 - conda_packages: gmsh -# conda_packages: 'gmsh pytrilinos' -# windows-py39: -# image: windows-latest -# python_version: 3.9 -# conda_packages: gmsh - - pool: - vmImage: $(image) - - steps: - - template: templates/install.yml - parameters: - python_version: $(python_version) - conda_packages: $(conda_packages) - - job: Test - dependsOn: Install strategy: matrix: linux-py27-pysparse: @@ -118,6 +82,11 @@ jobs: vmImage: $(image) steps: + - template: templates/install.yml + parameters: + python_version: $(python_version) + conda_packages: $(conda_packages) + - bash: | conda env export --name myEnvironment displayName: Environment @@ -132,8 +101,6 @@ jobs: displayName: Test - job: Docs - dependsOn: Install - variables: image: ubuntu-latest @@ -141,6 +108,11 @@ jobs: vmImage: ubuntu-latest steps: + - template: templates/install.yml + parameters: + python_version: 3.9 + conda_packages: 'sphinx future matplotlib pandas imagemagick' + - bash: | source activate myEnvironment pip install sphinxcontrib-bibtex From 3c00678d4df430ec19d27729041405b3e3580db9 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 11:20:10 -0400 Subject: [PATCH 154/175] Add jobs --- .azure/pipelines.yml | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index f8fa1a4171..b56815b07c 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -150,3 +150,71 @@ jobs: - publish: $(System.DefaultWorkingDirectory)/documentation/_build/latex/fipy.pdf artifact: fipy.pdf + + - job: Spelling + variables: + image: ubuntu-latest + + pool: + vmImage: ubuntu-latest + + steps: + - template: templates/install.yml + parameters: + python_version: 3.9 + conda_packages: 'hunspell' + + - bash: | + source activate myEnvironment + pip install pyspelling + displayName: Install pip packages + + - bash: | + wget -O en_US.aff https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.aff?id=a4473e06b56bfe35187e302754f6baaa8d75e54f + wget -O en_US.dic https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.dic?id=a4473e06b56bfe35187e302754f6baaa8d75e54f + displayName: Obtain dictionaries + + - bash: pyspelling + displayName: Check spelling + + - job: Lint + variables: + image: ubuntu-latest + + pool: + vmImage: ubuntu-latest + + steps: + - template: templates/install.yml + parameters: + python_version: 3.9 + conda_packages: 'numpy' + + - bash: | + source activate myEnvironment + pip install pylint + displayName: Install pip packages + + - bash: pylint setup.py + displayName: Check lint + + - job: Style + variables: + image: ubuntu-latest + + pool: + vmImage: ubuntu-latest + + steps: + - template: templates/install.yml + parameters: + python_version: 3.9 + conda_packages: 'numpy' + + - bash: | + source activate myEnvironment + pip install flake8 + displayName: Install pip packages + + - bash: flake8 setup.py + displayName: Check style From 91ff6286a26e49069115e05034fe48bce6f51d05 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 11:24:21 -0400 Subject: [PATCH 155/175] Activate environment --- .azure/pipelines.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index b56815b07c..fe5d26324e 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -174,7 +174,9 @@ jobs: wget -O en_US.dic https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.dic?id=a4473e06b56bfe35187e302754f6baaa8d75e54f displayName: Obtain dictionaries - - bash: pyspelling + - bash: | + source activate myEnvironment + pyspelling displayName: Check spelling - job: Lint @@ -195,7 +197,9 @@ jobs: pip install pylint displayName: Install pip packages - - bash: pylint setup.py + - bash: | + source activate myEnvironment + pylint setup.py displayName: Check lint - job: Style @@ -216,5 +220,7 @@ jobs: pip install flake8 displayName: Install pip packages - - bash: flake8 setup.py + - bash: | + source activate myEnvironment + flake8 setup.py displayName: Check style From ff11bee514b6b46f8353c4d06db69f4e68e153d9 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 12:11:34 -0400 Subject: [PATCH 156/175] Build unix binaries --- .azure/pipelines.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index fe5d26324e..dd100c4722 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -98,6 +98,7 @@ jobs: env: FIPY_SOLVERS: $(FIPY_SOLVERS) MPIRUN: $(MPIRUN) + OMP_NUM_THREADS: 1 displayName: Test - job: Docs @@ -224,3 +225,41 @@ jobs: source activate myEnvironment flake8 setup.py displayName: Check style + + - job: Binaries + variables: + image: ubuntu-latest + + pool: + vmImage: ubuntu-latest + + steps: + - template: templates/install.yml + parameters: + python_version: 3.9 + conda_packages: 'gmsh' + + - bash: git fetch origin --tags + displayName: Fetch tags + + - bash: | + source activate myEnvironment + python setup.py bdist_egg + python setup.py release --unix + displayName: Build package + + - bash: | + source activate myEnvironment + FIPY_VERSION=`python setup.py --version` + mkdir tmp + cd tmp + cp ../dist/FiPy-${FIPY_VERSION}.tar.gz . + tar zxvf FiPy-${FIPY_VERSION}.tar.gz + cd FiPy-${FIPY_VERSION} + python setup.py install + cd .. + python -c "import fipy; fipy.test()" + displayName: Test package + + - publish: $(System.DefaultWorkingDirectory)/dist/ + artifact: dist From ae2abe7a5117cb95853b4357ee394d529bacb5f8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 12:22:59 -0400 Subject: [PATCH 157/175] Build windows distribution --- .azure/pipelines.yml | 45 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index dd100c4722..fc96b474d1 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -227,17 +227,29 @@ jobs: displayName: Check style - job: Binaries - variables: - image: ubuntu-latest + strategy: + matrix: + unix: + image: ubuntu-latest + python_version: 3.9 + conda_packages: gmsh + FIPY_SOLVERS: petsc + MPIRUN: + windows: + image: windows-latest + python_version: 3.9 + conda_packages: gmsh + FIPY_SOLVERS: scipy + MPIRUN: pool: - vmImage: ubuntu-latest + vmImage: $(image) steps: - template: templates/install.yml parameters: - python_version: 3.9 - conda_packages: 'gmsh' + python_version: $(python_version) + conda_packages: $(conda_packages) - bash: git fetch origin --tags displayName: Fetch tags @@ -247,6 +259,14 @@ jobs: python setup.py bdist_egg python setup.py release --unix displayName: Build package + condition: startsWith(variables.image, 'ubuntu') + + - bash: | + source activate myEnvironment + python setup.py bdist_egg + python setup.py release --windows + displayName: Build package + condition: startsWith(variables.image, 'windows') - bash: | source activate myEnvironment @@ -260,6 +280,21 @@ jobs: cd .. python -c "import fipy; fipy.test()" displayName: Test package + condition: startsWith(variables.image, 'ubuntu') + + - bash: | + source activate myEnvironment + FIPY_VERSION=`python setup.py --version` + mkdir tmp + cd tmp + cp ../dist/FiPy-${FIPY_VERSION}.zip . + unzip FiPy-${FIPY_VERSION}.zip + cd FiPy-${FIPY_VERSION} + python setup.py install + cd .. + python -c "import fipy; fipy.test()" + displayName: Test package + condition: startsWith(variables.image, 'windows') - publish: $(System.DefaultWorkingDirectory)/dist/ artifact: dist From 9aa26d9d8b272dfa9885488d9f7a9139cdb3e3ca Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 14:14:27 -0400 Subject: [PATCH 158/175] Separately publish artifacts --- .azure/pipelines.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index fc96b474d1..347dcaacda 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -296,5 +296,8 @@ jobs: displayName: Test package condition: startsWith(variables.image, 'windows') - - publish: $(System.DefaultWorkingDirectory)/dist/ - artifact: dist + - publish: $(System.DefaultWorkingDirectory)/dist/*.tar.gz + condition: startsWith(variables.image, 'ubuntu') + + - publish: $(System.DefaultWorkingDirectory)/dist/*.zip + condition: startsWith(variables.image, 'windows') From c224d509268b7f2e61bfe4e4f989ddf47d1cc6b8 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 15:33:28 -0400 Subject: [PATCH 159/175] Install pytrilinos under Python 3.7 --- .azure/pipelines.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 347dcaacda..4a8f44cf41 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -35,12 +35,18 @@ jobs: conda_packages: gmsh FIPY_SOLVERS: scipy MPIRUN: - linux-py39-trilinos: + linux-py37-trilinos: image: ubuntu-latest - python_version: 3.9 + python_version: 3.7 conda_packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos MPIRUN: + linux-py37-trilinos-parallel: + image: ubuntu-latest + python_version: 3.7 + conda_packages: 'gmsh pytrilinos' + FIPY_SOLVERS: trilinos + MPIRUN: 'mpirun -np 2' macos-py27-pysparse: image: macos-latest python_version: 2.7 @@ -65,12 +71,18 @@ jobs: conda_packages: gmsh FIPY_SOLVERS: scipy MPIRUN: - macos-py39-trilinos: + macos-py37-trilinos: image: macos-latest - python_version: 3.9 + python_version: 3.7 conda_packages: 'gmsh pytrilinos' FIPY_SOLVERS: trilinos MPIRUN: + macos-py37-trilinos-parallel: + image: macos-latest + python_version: 3.7 + conda_packages: 'gmsh pytrilinos' + FIPY_SOLVERS: trilinos + MPIRUN: 'mpirun -np 2' windows-py39-scipy: image: windows-latest python_version: 3.9 From 7723d240f6a935ec19a2052e9bd21d7495f5bb38 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 15:43:27 -0400 Subject: [PATCH 160/175] Ensure mamba installed with correct python --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 3fb1b93091..84eeb41752 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -24,7 +24,7 @@ steps: - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults - conda create --yes --quiet --name myEnvironment --channel conda-forge mamba + conda create --yes --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba displayName: Create Anaconda environment - bash: | From 8cee89c55559a99edc2e6ef2961243c52aa340fa Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 30 Sep 2021 19:27:00 -0400 Subject: [PATCH 161/175] Distinguish artifacts correctly --- .azure/pipelines.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.azure/pipelines.yml b/.azure/pipelines.yml index 4a8f44cf41..00c4eff6e9 100644 --- a/.azure/pipelines.yml +++ b/.azure/pipelines.yml @@ -308,8 +308,5 @@ jobs: displayName: Test package condition: startsWith(variables.image, 'windows') - - publish: $(System.DefaultWorkingDirectory)/dist/*.tar.gz - condition: startsWith(variables.image, 'ubuntu') - - - publish: $(System.DefaultWorkingDirectory)/dist/*.zip - condition: startsWith(variables.image, 'windows') + - publish: $(System.DefaultWorkingDirectory)/dist/ + artifact: dist-$(Agent.OS) From e944573789cbe40d326437549d47243887c0a4a2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 18 Nov 2021 22:24:35 -0500 Subject: [PATCH 162/175] Ping the build --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 25b4e861d6..f7b67db016 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,7 @@ Overview ======== + | |CircleCI|_ |TravisCI|_ |AppVeyor|_ | |GitHub|_ |PyPI|_ |Codacy|_ |CondaForge|_ |Binder|_ | |gitter|_ |Depsy|_ |OpenHub|_ From 554270fd64240c605cf055a0e67b51a1c2b02789 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 18 Nov 2021 23:02:04 -0500 Subject: [PATCH 163/175] Disable f-string warning in pylint --- setup.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.cfg b/setup.cfg index 4a1322ff42..2c0fc78764 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,3 +9,6 @@ parentdir_prefix = [flake8] ignore = E731, W503 max-line-length = 88 + +[pylint] +disable = consider-using-f-string From 2128fd48a2426af56e9660d3f9da15db90786a3e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 18 Nov 2021 23:26:07 -0500 Subject: [PATCH 164/175] Fix pylint section name --- setup.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 2c0fc78764..6339957e2b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,5 +10,5 @@ parentdir_prefix = ignore = E731, W503 max-line-length = 88 -[pylint] -disable = consider-using-f-string +[pylint.messages_control] +disable=consider-using-f-string From 0544d29b60ae273ddcc2bc9755847103dbd29dbb Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 18 Nov 2021 23:39:49 -0500 Subject: [PATCH 165/175] Attempt to only pip on Py3k --- .azure/templates/install.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 84eeb41752..2025809fe9 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -34,6 +34,8 @@ steps: displayName: Install Anaconda packages - bash: | - source activate myEnvironment - pip install scikit-fmm + if [[ ${{ parameters.python_version }} = "2.7" ]]; then + source activate myEnvironment + pip install scikit-fmm + fi displayName: Install pip packages From 605cacc1bf723810b7ac285cf7ccf25ba9e86eb9 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Thu, 18 Nov 2021 23:52:24 -0500 Subject: [PATCH 166/175] Fix conditional --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 2025809fe9..90f393926f 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -34,7 +34,7 @@ steps: displayName: Install Anaconda packages - bash: | - if [[ ${{ parameters.python_version }} = "2.7" ]]; then + if [[ ${{ parameters.python_version }} != "2.7" ]]; then source activate myEnvironment pip install scikit-fmm fi From 7c14c05e9c203802102a5183f1f0f183810bbcad Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 19 Nov 2021 23:45:41 -0500 Subject: [PATCH 167/175] mamba install from Py3k mamba doesn't work right from within a Python 2.7 environment --- .azure/templates/install.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 90f393926f..98682e472d 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -24,13 +24,12 @@ steps: - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults - conda create --yes --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba + conda create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba displayName: Create Anaconda environment - bash: | - source activate myEnvironment - mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy - mamba install --quiet --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} + mamba install --quiet --name myEnvironment --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy + mamba install --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} displayName: Install Anaconda packages - bash: | From c8af557e3ef44a813bd7b8c5e2ca231f32b29003 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 19 Nov 2021 23:59:34 -0500 Subject: [PATCH 168/175] Install mamba in base environment --- .azure/templates/install.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 98682e472d..e20133f458 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -24,7 +24,8 @@ steps: - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults - conda create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba + conda install --quiet --channel conda-forge mamba + mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} displayName: Create Anaconda environment - bash: | From 4b2bf8d80130c3b14b4bbf27df4cf3487333f9ec Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 21 Nov 2021 22:03:32 -0500 Subject: [PATCH 169/175] install mamba with mamba Troubleshooting how environment has changed from 605cacc --- .azure/templates/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index e20133f458..36444b8327 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -25,7 +25,7 @@ steps: conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults conda install --quiet --channel conda-forge mamba - mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} + mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba displayName: Create Anaconda environment - bash: | From 16257a9880411a6e59d18927c8104932d538eca2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 21 Nov 2021 22:26:36 -0500 Subject: [PATCH 170/175] Install libGL on linux --- .azure/templates/install.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 36444b8327..4a24352132 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -20,7 +20,14 @@ steps: - bash: sudo chown -R $USER $CONDA displayName: Take ownership of conda installation condition: startsWith(variables.image, 'macos') - + + - bash: | + apt-get --yes install libglu1-mesa + apt-get --yes install libgl1-mesa-glx + apt-get --yes install libxrender1 + displayName: Install libGL + condition: startsWith(variables.image, 'ubuntu') + - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults From be2b76e129a1b74d8eb7fc6fb7845fe1780e7536 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 21 Nov 2021 22:30:43 -0500 Subject: [PATCH 171/175] Install libGL as sudoer --- .azure/templates/install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 4a24352132..a2b2f5296b 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -22,9 +22,9 @@ steps: condition: startsWith(variables.image, 'macos') - bash: | - apt-get --yes install libglu1-mesa - apt-get --yes install libgl1-mesa-glx - apt-get --yes install libxrender1 + sudo apt-get --yes install libglu1-mesa + sudo apt-get --yes install libgl1-mesa-glx + sudo apt-get --yes install libxrender1 displayName: Install libGL condition: startsWith(variables.image, 'ubuntu') From 5a52c546a90baa8c86f5ab7c721efc8625691559 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Sun, 21 Nov 2021 23:27:35 -0500 Subject: [PATCH 172/175] Differentiate windows mamba install --- .azure/templates/install.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index a2b2f5296b..bb276a2b31 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -34,6 +34,16 @@ steps: conda install --quiet --channel conda-forge mamba mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba displayName: Create Anaconda environment + condition: not(startsWith(variables.image, 'windows')) + + - bash: | + conda config --set always_yes yes --set changeps1 no + conda config --remove channels defaults + source activate myEnvironment + conda install --quiet --channel conda-forge mamba + mamba create --quiet --channel conda-forge python=${{ parameters.python_version }} mamba + displayName: Create Anaconda environment + condition: startsWith(variables.image, 'windows') - bash: | mamba install --quiet --name myEnvironment --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy From 33f408ecf12a8ee4e6902e6e0a462010aefc24c4 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 22 Nov 2021 08:52:47 -0500 Subject: [PATCH 173/175] Differentiate Py2.7 and Py3k mamba installs mamba doesn't work from a Py2.7 environment, but mamba needs to be installed in a Py3k environment for some reason --- .azure/templates/install.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index bb276a2b31..87b6ec6ef5 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -31,21 +31,21 @@ steps: - bash: | conda config --set always_yes yes --set changeps1 no conda config --remove channels defaults - conda install --quiet --channel conda-forge mamba - mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba - displayName: Create Anaconda environment - condition: not(startsWith(variables.image, 'windows')) - - - bash: | - conda config --set always_yes yes --set changeps1 no - conda config --remove channels defaults - source activate myEnvironment - conda install --quiet --channel conda-forge mamba - mamba create --quiet --channel conda-forge python=${{ parameters.python_version }} mamba + if [[ ${{ parameters.python_version }} == "2.7" ]]; then + # mamba doesn't work in Py2.7; do mamba installs from base + conda install --quiet --channel conda-forge mamba + mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba + else + conda create --yes --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba + fi displayName: Create Anaconda environment - condition: startsWith(variables.image, 'windows') - bash: | + if [[ ${{ parameters.python_version }} != "2.7" ]]; then + # mamba doesn't work in Py2.7 + # only mamba installs from environment on Py3k + source activate myEnvironment + fi mamba install --quiet --name myEnvironment --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy mamba install --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} displayName: Install Anaconda packages From cc718ca96bfb23b51bb5e140bcf9bbc7dbddf9bb Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 22 Nov 2021 09:00:09 -0500 Subject: [PATCH 174/175] Fix syntax for mamba installs from active environment --- .azure/templates/install.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.azure/templates/install.yml b/.azure/templates/install.yml index 87b6ec6ef5..7fa4756e8c 100644 --- a/.azure/templates/install.yml +++ b/.azure/templates/install.yml @@ -36,18 +36,22 @@ steps: conda install --quiet --channel conda-forge mamba mamba create --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba else + # mamba needs to be installed in the Py3k environment for some reason conda create --yes --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} mamba fi displayName: Create Anaconda environment - bash: | - if [[ ${{ parameters.python_version }} != "2.7" ]]; then - # mamba doesn't work in Py2.7 - # only mamba installs from environment on Py3k + if [[ ${{ parameters.python_version }} == "2.7" ]]; then + # mamba doesn't work in Py2.7; do mamba installs from base + mamba install --quiet --name myEnvironment --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy + mamba install --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} + else + # do mamba installs from environment on Py3k source activate myEnvironment + mamba install --quiet --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy + mamba install --quiet --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} fi - mamba install --quiet --name myEnvironment --channel conda-forge --only-deps python=${{ parameters.python_version }} fipy - mamba install --quiet --name myEnvironment --channel conda-forge python=${{ parameters.python_version }} ${{ parameters.conda_packages }} displayName: Install Anaconda packages - bash: | From d5d547076cea20aced261735351a1d8cc083e7e2 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Mon, 22 Nov 2021 21:51:18 -0500 Subject: [PATCH 175/175] Remove older, slower CIs TravisCI, in particular, appears to have [abandoned](https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing) [Open Source](https://docs.travis-ci.com/user/billing-overview/) --- .appveyor.yml | 124 -------- .circleci/config.yml | 667 ------------------------------------------- .travis.yml | 79 ----- 3 files changed, 870 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .circleci/config.yml delete mode 100644 .travis.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index b16f69e013..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,124 +0,0 @@ -# This file was adapted from what's generated by conda-smithy. - -image: -- Visual Studio 2015 -- Visual Studio 2019 - -environment: - - matrix: - - - TARGET_ARCH: x64 - CONDA_PY: 27 - CONDA_INSTALL_LOCN: C:\\Miniconda-x64 - FIPY_SOLVERS: pysparse - -# - TARGET_ARCH: x64 -# CONDA_PY: 27 -# CONDA_INSTALL_LOCN: C:\\Miniconda-x64 -# FIPY_SOLVERS: pysparse -# FIPY_INLINE: 1 - -# - TARGET_ARCH: x86 -# CONDA_PY: 27 -# CONDA_INSTALL_LOCN: C:\\Miniconda -# FIPY_SOLVERS: scipy - - - TARGET_ARCH: x64 - CONDA_PY: 27 - CONDA_INSTALL_LOCN: C:\\Miniconda-x64 - FIPY_SOLVERS: scipy - -# - TARGET_ARCH: x86 -# CONDA_PY: 38 -# CONDA_INSTALL_LOCN: C:\\Miniconda38 -# FIPY_SOLVERS: scipy - - - TARGET_ARCH: x64 - CONDA_PY: 38 - CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 - FIPY_SOLVERS: scipy - -matrix: - exclude: - - image: Visual Studio 2015 - CONDA_PY: 38 - - - image: Visual Studio 2019 - CONDA_PY: 27 - -# We always use a 64-bit machine, but can build x86 distributions -# with the TARGET_ARCH variable. -platform: - - x64 - -# Enable remote desktop on CI -# https://www.appveyor.com/docs/how-to/rdp-to-build-worker/ -# init: -# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - -install: - # If there is a newer build queued for the same PR, cancel this one. - - cmd: | - powershell -Command "(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/conda-forge/conda-forge-build-setup-feedstock/master/recipe/ff_ci_pr_build.py', 'ff_ci_pr_build.py')" - ff_ci_pr_build -v --ci "appveyor" "%APPVEYOR_ACCOUNT_NAME%/%APPVEYOR_PROJECT_SLUG%" "%APPVEYOR_BUILD_NUMBER%" "%APPVEYOR_PULL_REQUEST_NUMBER%" - del ff_ci_pr_build.py - - # Cywing's git breaks conda-build. (See https://github.com/conda-forge/conda-smithy-feedstock/pull/2.) - - cmd: rmdir C:\cygwin /s /q - - # Add path, activate `conda` and update conda. - - cmd: call %CONDA_INSTALL_LOCN%\Scripts\activate.bat - - cmd: conda.exe update --yes --quiet conda - - - cmd: set PYTHONUNBUFFERED=1 - - # Add our channels. - - cmd: conda.exe config --set show_channel_urls true - - cmd: conda.exe config --set always_yes yes - - cmd: conda.exe config --set changeps1 no - - cmd: conda.exe config --remove channels defaults - - cmd: if "%CONDA_PY%" == "27" conda.exe config --add channels defaults - - cmd: conda.exe config --add channels conda-forge - - # Configure the VM. - - cmd: if "%TARGET_ARCH%" == "x64" if "%CONDA_PY%" == "27" conda.exe install --quiet --name root python=2.7 fipy - - cmd: if "%TARGET_ARCH%" == "x64" if "%CONDA_PY%" == "38" conda.exe install --quiet --name root python=3 fipy gmsh - - cmd: conda.exe remove --quiet --force fipy - # FIXME: fipy recipe on conda-forge doesn't have gmsh compatible with Python 2.7 - - ps: | - $ErrorActionPreference = "Stop"; - if (($env:TARGET_ARCH -eq "x64") -and ($env:CONDA_PY -eq "27")) { - Invoke-WebRequest -Uri 'https://gmsh.info/bin/Windows/gmsh-4.3.0-Windows64.zip' -OutFile gmsh-4.3.0-Windows64.zip - Add-Type -A 'System.IO.Compression.FileSystem' - Expand-Archive gmsh-4.3.0-Windows64.zip -DestinationPath . - copy gmsh-4.3.0-Windows64\gmsh.exe $env:CONDA_INSTALL_LOCN\Scripts\ - } - - cmd: if "%TARGET_ARCH%" == "x86" conda.exe install --quiet --name root python numpy scipy matplotlib - - cmd: if "%TARGET_ARCH%" == "x86" if "%CONDA_PY%" == "27" conda.exe install --quiet --name root mayavi weave - - cmd: if "%TARGET_ARCH%" == "x86" if "%FIPY_SOLVERS%" == "pysparse" conda.exe install --quiet --name root pysparse - - - cmd: pip install scikit-fmm - -# Skip .NET project specific build phase. -build: off - -build_script: - - python setup.py release --windows - -test_script: - - python setup.py egg_info - - if defined FIPY_INLINE python setup.py test 1> NUL 2>&1 - - python setup.py test --deprecation-errors - - conda env export - -artifacts: - - path: dist\FiPy-*.zip - name: Win Installer - -# deploy_script: -# - cmd: upload_or_check_non_existence .\recipe guyer --channel=main - -# Hold remote desktop open -# on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 0f644066ab..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,667 +0,0 @@ -# Python CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-python/ for more details -# -version: 2.1 - -defaults: &defaults - working_directory: ~/project - -defaults2: &defaults2 - <<: *defaults - - docker: - - image: continuumio/miniconda3 - -defaults3: &defaults3 - <<: *defaults - - docker: - - image: continuumio/miniconda3 - -commands: - createenv: - description: "Create conda environment" - - parameters: - condaenv: - type: string - default: "cache" - - packages: - type: string - default: "" - - python: - type: string - default: "python" - - steps: - - run: - name: Create Conda Environment - command: | - mamba create -v --quiet --prefix << parameters.condaenv >> --show-channel-urls --channel conda-forge "<< parameters.python >>" << parameters.packages >> - source activate ~/project/<< parameters.condaenv >> - mamba remove --quiet --channel conda-forge --force fipy - pip install scikit-fmm - - test_fipy: - description: "Run FiPy Tests" - - parameters: - mpirun: - type: string - default: "" - condaenv: - type: string - default: "test-environment-27" - - steps: - - run: - name: Install libGL - command: | - apt-get --yes update - apt-get --yes install libglu1-mesa - apt-get --yes install libgl1-mesa-glx - apt-get --yes install libxrender1 - - - checkout - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: Output Environment - command: | - conda env export --prefix ~/project/<< parameters.condaenv >> - - - run: - name: Run Tests - no_output_timeout: 30m - command: | - source activate ~/project/<< parameters.condaenv >> - python setup.py egg_info - if [[ ! -z "${FIPY_INLINE}" ]]; then - << parameters.mpirun >> python setup.py test > /dev/null 2>&1 || true; - fi - << parameters.mpirun >> python setup.py test --deprecation-errors - - - store_artifacts: - path: test-reports - destination: test-reports - - build_html_docs: - description: "Build HTML Docs" - - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - run: - name: Build Docs - command: | - source activate ~/project/<< parameters.condaenv >> - export ETS_TOOLKIT=null - python setup.py build_docs --html - tar -czf ~/project/html.tar.gz -C ~/project/documentation/_build html - - - store_artifacts: - path: ~/project/html.tar.gz - - - store_artifacts: - path: ~/project/documentation/_build/html - - build_pdf_docs: - description: "Build PDF Docs" - - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - run: - name: Build Docs - command: | - source activate ~/project/<< parameters.condaenv >> - export ETS_TOOLKIT=null - python setup.py build_docs --pdf - - - store_artifacts: - path: ~/project/documentation/_build/latex/fipy.pdf - - # localize changes to cache name to these two commands - save_conda_cache: - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - save_cache: - paths: - - /opt/conda - - /root/.cache/pip - key: v14-dependencies-{{ arch }}-<< parameters.condaenv >> - - restore_conda_cache: - description: "Restore cache holding conda and pip" - - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - restore_cache: - keys: - - v14-dependencies-{{ arch }}-<< parameters.condaenv >> - # fallback to using the latest cache if no exact match is found - - v14-dependencies- - - install_dependencies: - steps: - - run: - name: Install Dependencies - command: | - apt-get --yes update - apt-get --yes install build-essential - conda config --set always_yes yes --set changeps1 no - conda config --remove channels defaults - conda install --channel conda-forge mamba - - remove_extracted_conda_packages: - description: "force conda to download packages into the cache and then - clean out extracted packages - after https://gist.github.com/mcg1969/cbb1760cea6b0671959d8cbf957c89bf" - steps: - - run: - name: Remove Extracted Conda Packages - command: | - conda clean --packages - - install_conda_packages: - description: "Restore conda environment and install packages" - - parameters: - packages: - type: string - default: "" - condaenv: - type: string - default: "test-environment-27" - python: - type: string - default: "python" - - steps: - # Download and cache dependencies - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - install_dependencies - - - createenv: - condaenv: << parameters.condaenv >> - packages: << parameters.packages >> - python: << parameters.python >> - - - remove_extracted_conda_packages - - - save_conda_cache: - condaenv: << parameters.condaenv >> - - - persist_to_workspace: - root: ~/project - paths: - - << parameters.condaenv >> - - install_pip_packages: - description: "Check pip installation" - - parameters: - packages: - type: string - default: "python" - - steps: - - checkout - - - attach_workspace: - at: ~/project - - - run: - name: Install with Pip - command: | - conda create -v --quiet --name pipenv --show-channel-urls --channel conda-forge << parameters.packages >> - source activate pipenv - pip install -e . - -jobs: - conda2_env: - <<: *defaults2 - - steps: - - install_conda_packages: - python: "python=2.7" - packages: "fipy \"traitsui<7.0.0\" \"gmsh<4.0\"" - condaenv: "test-environment-27" - - conda3_env: - <<: *defaults3 - - steps: - - install_conda_packages: - python: "python=3" - packages: "fipy pytrilinos gmsh" - condaenv: "test-environment-36" - - pip_env: - <<: *defaults3 - - steps: - - install_pip_packages: - packages: "python=3" - - test-27-pysparse: - <<: *defaults2 - - steps: - - test_fipy: - condaenv: test-environment-27 - environment: - FIPY_SOLVERS: pysparse - - test-27-inline: - <<: *defaults2 - - steps: - - test_fipy: - condaenv: test-environment-27 - environment: - FIPY_SOLVERS: pysparse - FIPY_INLINE: 1 - - test-27-scipy: - <<: *defaults2 - - steps: - - test_fipy: - condaenv: test-environment-27 - environment: - FIPY_SOLVERS: scipy - - test-27-petsc-serial: - <<: *defaults2 - - steps: - - test_fipy: - condaenv: test-environment-27 - environment: - FIPY_SOLVERS: petsc - - test-27-petsc-parallel: - <<: *defaults2 - - steps: - - test_fipy: - mpirun: "mpirun -np 2" - condaenv: test-environment-27 - environment: - FIPY_SOLVERS: petsc - OMP_NUM_THREADS: 1 - - test-36-scipy: - <<: *defaults3 - - steps: - - test_fipy: - condaenv: test-environment-36 - environment: - FIPY_SOLVERS: scipy - - test-36-trilinos-serial: - <<: *defaults3 - - steps: - - test_fipy: - condaenv: test-environment-36 - environment: - FIPY_SOLVERS: trilinos - - test-36-trilinos-parallel: - <<: *defaults3 - - steps: - - test_fipy: - mpirun: "mpirun -np 2" - condaenv: test-environment-36 - environment: - FIPY_SOLVERS: trilinos - OMP_NUM_THREADS: 1 - - test-36-petsc-serial: - <<: *defaults3 - - steps: - - test_fipy: - condaenv: test-environment-36 - environment: - FIPY_SOLVERS: petsc - - test-36-petsc-parallel: - <<: *defaults3 - - steps: - - test_fipy: - mpirun: "mpirun -np 2" - condaenv: test-environment-36 - environment: - FIPY_SOLVERS: petsc - OMP_NUM_THREADS: 1 - - pylint: - <<: *defaults2 - - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - checkout - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: Lint - command: | - source activate ~/project/<< parameters.condaenv >> - pip install pylint - pylint setup.py - - flake8: - <<: *defaults2 - - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - checkout - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: Lint - command: | - source activate ~/project/<< parameters.condaenv >> - pip install flake8 - flake8 setup.py - - black: - <<: *defaults3 - - parameters: - condaenv: - type: string - default: "test-environment-36" - - steps: - - checkout - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: Lint - command: | - source activate ~/project/<< parameters.condaenv >> - mamba install --channel conda-forge black - black --target-version py27 --fast --diff --check setup.py - - pyspelling: - <<: *defaults3 - - parameters: - condaenv: - type: string - default: "test-environment-36" - - steps: - - checkout - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: Spell Check - command: | - source activate ~/project/<< parameters.condaenv >> - mamba install --channel conda-forge hunspell - pip install pyspelling - wget -O en_US.aff https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.aff?id=a4473e06b56bfe35187e302754f6baaa8d75e54f - wget -O en_US.dic https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.dic?id=a4473e06b56bfe35187e302754f6baaa8d75e54f - pyspelling - - build-27-docs: - <<: *defaults2 - - parameters: - condaenv: - type: string - default: "test-environment-27" - - steps: - - checkout - - - run: - name: fetch tags - command: git fetch origin --tags - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: install sphinx - command: | - source activate ~/project/<< parameters.condaenv >> - mamba install --channel conda-forge sphinx future - pip install 'sphinxcontrib-bibtex<=0.4.2' - pip install numpydoc - mamba install --channel conda-forge matplotlib pandas imagemagick - - - build_html_docs: - condaenv: << parameters.condaenv >> - - build-36-docs: - <<: *defaults3 - - parameters: - condaenv: - type: string - default: "test-environment-36" - - steps: - - checkout - - - run: - name: fetch tags - command: git fetch origin --tags - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: install sphinx - command: | - source activate ~/project/<< parameters.condaenv >> - mamba install --channel conda-forge sphinx future - pip install sphinxcontrib-bibtex - pip install numpydoc - mamba install --channel conda-forge matplotlib pandas imagemagick - - - run: - name: Install LaTeX - command: | - apt-get --yes update - apt-get --yes install texlive-latex-base - apt-get --yes install texlive-fonts-recommended - apt-get --yes install texlive-fonts-extra - apt-get --yes install texlive-latex-extra - apt-get --yes install texlive-science - apt-get --yes install texlive-extra-utils - - - build_html_docs: - condaenv: << parameters.condaenv >> - - - build_pdf_docs: - condaenv: << parameters.condaenv >> - - build-binaries: - <<: *defaults3 - - parameters: - condaenv: - type: string - default: "test-environment-36" - - steps: - - run: - name: Install libGL - command: | - apt-get --yes update - apt-get --yes install libglu1-mesa - apt-get --yes install libgl1-mesa-glx - apt-get --yes install libxrender1 - - - checkout - - - run: - name: fetch tags - command: git fetch origin --tags - - - restore_conda_cache: - condaenv: << parameters.condaenv >> - - - attach_workspace: - at: ~/project - - - run: - name: build and test tarball - command: | - source activate ~/project/<< parameters.condaenv >> - python setup.py bdist_egg - python setup.py release --unix - FIPY_VERSION=`python setup.py --version` - mkdir tmp - cd tmp - cp ../dist/FiPy-${FIPY_VERSION}.tar.gz . - tar zxvf FiPy-${FIPY_VERSION}.tar.gz - cd FiPy-${FIPY_VERSION} - python setup.py install - cd .. - python -c "import fipy; fipy.test()" - - - store_artifacts: - path: ~/project/dist - - -workflows: - version: 2 - - test: - jobs: - - conda2_env - - conda3_env -# - build-27-docs: -# requires: -# - conda2_env - - pip_env - - build-36-docs: - requires: - - conda3_env - - pylint: - requires: - - conda2_env - - flake8: - requires: - - conda2_env - - black: - requires: - - conda3_env - - pyspelling: - requires: - - conda3_env - - test-27-pysparse: - requires: - - conda2_env -# - test-27-inline: -# requires: -# - conda2_env -# - test-27-scipy: -# requires: -# - conda2_env - - test-27-petsc-serial: - requires: - - conda2_env - - test-27-petsc-parallel: - requires: - - conda2_env - - test-36-scipy: - requires: - - conda3_env - - test-36-trilinos-serial: - requires: - - conda3_env - - test-36-trilinos-parallel: - requires: - - conda3_env - - test-36-petsc-serial: - requires: - - conda3_env - - test-36-petsc-parallel: - requires: - - conda3_env - - build-binaries: - requires: - - conda3_env -# - build-36-docs -# - pylint -# - flake8 -# - black -# - pyspelling -# - test-27-pysparse -# - test-27-trilinos-serial -# - test-27-trilinos-parallel -# - test-27-petsc-serial -# - test-27-petsc-parallel -# - test-36-scipy -# - test-36-petsc-serial -# - test-36-petsc-parallel diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 155ae90cdc..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,79 +0,0 @@ -# inspired by http://conda.pydata.org/docs/travis.html -# -# language: python causes grief on osx -language: generic -os: - - osx - # - linux -env: - - TRAVIS_PYTHON_VERSION=2.7 MPIRUN= FIPY_SOLVERS=pysparse -# - TRAVIS_PYTHON_VERSION=2.7 MPIRUN= FIPY_SOLVERS=pysparse FIPY_INLINE=1 -# - TRAVIS_PYTHON_VERSION=2.7 MPIRUN= FIPY_SOLVERS=scipy - - TRAVIS_PYTHON_VERSION=3.6 MPIRUN= FIPY_SOLVERS=trilinos - - TRAVIS_PYTHON_VERSION=3.6 MPIRUN="mpirun -np 2" FIPY_SOLVERS=trilinos -# - TRAVIS_PYTHON_VERSION=2.7 MPIRUN= FIPY_SOLVERS=petsc -# - TRAVIS_PYTHON_VERSION=2.7 MPIRUN="mpirun -np 2" FIPY_SOLVERS=petsc - - TRAVIS_PYTHON_VERSION=3.6 MPIRUN= FIPY_SOLVERS=scipy - - TRAVIS_PYTHON_VERSION=3.6 MPIRUN= FIPY_SOLVERS=petsc - - TRAVIS_PYTHON_VERSION=3.6 MPIRUN="mpirun -np 2" FIPY_SOLVERS=petsc -cache: apt -branches: - except: - - nist-pages -before_install: - # sudo ln -s /usr/lib/lapack/liblapack.so.3gf /usr/lib/lapack/liblapack.so.3; - # sudo ldconfig; - - if [[ $TRAVIS_OS_NAME = "linux" ]]; then - sudo apt-get update; - fi - # We do this conditionally because it saves us some downloading if the - # version is the same. - - PY3K=$(echo "$TRAVIS_PYTHON_VERSION >= 3.0" | bc) - - if [[ $TRAVIS_OS_NAME = "linux" ]]; then - export MINICONDA_OS_NAME=Linux; - elif [[ $TRAVIS_OS_NAME = "osx" ]]; then - export MINICONDA_OS_NAME=MacOSX; - fi - - if [[ $PY3K -eq 1 ]]; then - export MINICONDA_VERSION=3; - else - export MINICONDA_VERSION=2; - fi - - wget https://repo.continuum.io/miniconda/Miniconda${MINICONDA_VERSION}-latest-${MINICONDA_OS_NAME}-x86_64.sh -O miniconda.sh; - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - hash -r - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - - conda install --channel conda-forge mamba - - mamba create --quiet --name test-environment --show-channel-urls --channel conda-forge python=$TRAVIS_PYTHON_VERSION fipy pytrilinos; - - source activate test-environment - - mamba remove --quiet --channel conda-forge --force fipy - - if [[ $PY3K -eq 0 ]]; then - mamba install --channel conda-forge "traitsui<7.0.0" "gmsh<4.0"; - else - mamba install --channel conda-forge gmsh; - fi - # Useful for debugging any issues with conda - - conda info -a - - pip install scikit-fmm -install: - - python setup.py install -before_script: - # lack of display causes tests to abort at VtkViewer - # Workaround @ http://docs.enthought.com/mayavi/mayavi/tips.html#rendering-using-the-virtual-framebuffer - # and https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI - - if [[ $TRAVIS_OS_NAME = "linux" ]]; then - export DISPLAY=:99.0; - sh -e /etc/init.d/xvfb start; - sleep 3; - fi - # inline must be run twice to clear out compiler warnings - # we don't care if it fails the first time - - if [[ ! -z "${FIPY_INLINE}" ]]; then - travis_wait 40 $MPIRUN python setup.py test || true; - fi -script: - - $MPIRUN python setup.py test --deprecation-errors; -after_success: - - conda env export