
org.solovyev.common.math.algorithms.ExplicitFiniteDifferenceMethod Maven / Gradle / Ivy
The newest version!
package org.solovyev.common.math.algorithms;
import org.jetbrains.annotations.NotNull;
import org.solovyev.common.math.Conditions;
import org.solovyev.common.math.Function;
import org.solovyev.common.math.matrix.DoubleArrayMatrix;
import org.solovyev.common.math.matrix.Matrix;
import org.solovyev.common.math.matrix.MatrixUtils;
import org.solovyev.common.interval.SimpleInterval;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* User: SerSo
* Date: 18.05.2009
* Time: 0:18:29
*/
/**
* brief: solving equation: dU/dt = d^2U/dx^2 + f (x, t) where U(x, t) , f(x, t) - functions, U - unknown, f - known
* with conditions: 1. at x0 = a, x1 = b: U(x0, t) = U(x1, t) = 0
* 2. at t0 : U(x, t0) = exp(t0) * sin(PI *x)
*/
public class ExplicitFiniteDifferenceMethod extends AbstractAlgorithm> {
public static class Input {
private final int xNum;
private final int tNum;
private final SimpleInterval xInterval;
private final SimpleInterval tInterval;
private final Double xStep;
private final Double tStep;
private final Conditions conditions;
private final Function addFunction;
private final Matrix exactSolutionForU;
public Input(int xNum, int tNum, SimpleInterval xInterval, SimpleInterval tInterval, Conditions conditions, Function addFunction, Matrix exactSolutionForU) {
this.xNum = xNum;
this.tNum = tNum;
this.xInterval = xInterval;
this.tInterval = tInterval;
this.xStep = xInterval.dist() / (xNum - 1);
this.tStep = tInterval.dist() / (tNum - 1);
this.conditions = conditions;
this.addFunction = addFunction;
this.exactSolutionForU = exactSolutionForU;
}
}
@Override
public ExplicitFiniteDifferenceMethod init(@NotNull Input input) {
super.init(input);
this.result = new DoubleArrayMatrix(input.xNum, input.tNum);
if (input.conditions != null) {
for (int i = 0; i < input.xNum; i++) {
result.set(i, 0, input.conditions.getEntryCondition().getValue(input.tInterval.getStart(), i * input.xStep + input.xInterval.getStart()));
}
for (int j = 1; j < input.tNum; j++) {
result.set(0, j, input.conditions.getStartCondition0().getValue(j * input.tStep + input.tInterval.getStart(), input.xInterval.getStart()));
result.set(input.xNum - 1, j, input.conditions.getStartCondition1().getValue(j * input.tStep + input.tInterval.getStart(), input.xInterval.getEnd()));
}
} else {
//using exact solution
//this.exactSolution.transpose();
for (int i = 0; i < input.xNum; i++) {
result.set(i, 0, this.input.exactSolutionForU.get(i, 0));
}
for (int j = 1; j < input.tNum; j++) {
result.set(0, j, this.input.exactSolutionForU.get(0, j));
result.set(input.xNum - 1, j, this.input.exactSolutionForU.get(input.xNum - 1, j));
}
}
return this;
}
public Matrix doAlgorithm() {
//finding solution by explicit difference method
double lambda = input.tStep / Math.pow(input.xStep, 2);
for (int j = 1; j < this.input.tNum; j++) {
for (int i = 1; i < this.input.xNum - 1; i++) {
result.set(i, j, lambda * result.get(i + 1, j - 1) + (1 - 2 * lambda) * result.get(i, j - 1) + lambda * result.get(i - 1, j - 1) + input.tStep * this.input.addFunction.getValue(getT(j - 1), getX(i)));
}
}
return result;
}
private double getT(int j) {
return input.tStep * j + input.tInterval.getStart();
}
private double getX(int i) {
return input.xStep * i + input.xInterval.getStart();
}
@SuppressWarnings({"UnusedDeclaration"})
public static void mainMatlab(String paramsFile, String fileToSave) throws IOException {
String[] str = new String[2];
str[0] = paramsFile;
str[1] = fileToSave;
main(str);
}
public static void main(String[] arg) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(arg[0]));
SimpleInterval xInt = new SimpleInterval(Double.valueOf(in.readLine()), Double.valueOf(in.readLine()));
SimpleInterval tInt = new SimpleInterval(Double.valueOf(in.readLine()), Double.valueOf(in.readLine()));
ExplicitFiniteDifferenceMethod efdm = new ExplicitFiniteDifferenceMethod();
efdm.init(new Input(Double.valueOf(in.readLine()).intValue(), Double.valueOf(in.readLine()).intValue(), xInt, tInt,
new Conditions(new StartCondition0(), new StartCondition1(), new EntryCondition()), new AddFunction(), null));
in.close();
efdm.doAlgorithm();
String fName;
if (arg.length > 1) {
fName = arg[1];
} else {
fName = "result_" + ExplicitFiniteDifferenceMethod.class.toString() + ".txt";
}
MatrixUtils.saveMatrixInMatlabRepresentation(efdm.getResult(), fName);
}
private static class AddFunction implements Function {
public double getValue(double... params) {
return Math.exp(-params[0]) * Math.sin(Math.PI * params[1]) * (Math.PI * Math.PI - 1);
}
}
private static class EntryCondition implements Function {
public double getValue(double... params) {
return Math.exp(-params[0]) * Math.sin(Math.PI * params[1]);
}
}
private static class StartCondition0 implements Function {
public double getValue(double... params) {
return 0d;
}
}
private static class StartCondition1 implements Function {
public double getValue(double... params) {
return 0d;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy