tmp update
This commit is contained in:
commit
e845af9616
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"iosfwd": "cpp"
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -8,26 +8,18 @@
|
|||||||
#include "algorithm"
|
#include "algorithm"
|
||||||
#include "ctime"
|
#include "ctime"
|
||||||
|
|
||||||
#include "gctl/gctl_stream.h"
|
#include "gctl/core.h"
|
||||||
#include "gctl/gctl_heapsort.h"
|
#include "gctl/geometry.h"
|
||||||
#include "gctl/gctl_geometry2d.h"
|
#include "gctl/io.h"
|
||||||
#include "gctl/gctl_triangle_io.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
struct vertex;
|
struct vertex;
|
||||||
struct ele;
|
struct ele;
|
||||||
|
|
||||||
struct source : public gctl::point2d_c
|
struct vertex : public gctl::vertex2dc
|
||||||
{
|
|
||||||
double rad;
|
|
||||||
double slow;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vertex : public gctl::vertex2d_c
|
|
||||||
{
|
{
|
||||||
int tag = 0; //0 = far away, 1 = close, 2 = active
|
int tag = 0; //0 = far away, 1 = close, 2 = active
|
||||||
double slow; // slow are constant within a element. a mean value must be set in local update
|
|
||||||
double time = 1e+30;
|
double time = 1e+30;
|
||||||
double syn_time = 1e+30; //synthetic direct arrive time (only for error test)
|
double syn_time = 1e+30; //synthetic direct arrive time (only for error test)
|
||||||
vector<vertex*> v_neigh; //neighbor vertex unknown amount
|
vector<vertex*> v_neigh; //neighbor vertex unknown amount
|
||||||
@ -112,23 +104,20 @@ public:
|
|||||||
int ReadFiles(char* filename);
|
int ReadFiles(char* filename);
|
||||||
// output a Gmsh (.msh) file
|
// output a Gmsh (.msh) file
|
||||||
int OutMsh(char* filename, bool tag);
|
int OutMsh(char* filename, bool tag);
|
||||||
// initialize node slowness. slowness of the source will be used if default slowness is zero.
|
|
||||||
void InitNodeSlowness(double default_slow = 0.0);
|
|
||||||
// add abnormal slowness
|
// add abnormal slowness
|
||||||
void SetRectangeSlowness(double ab_slow,double xmin,double xmax,double ymin,double ymax);
|
void SetRectangeSlowness(double ab_slow,double xmin,double xmax,double ymin,double ymax);
|
||||||
// initialize triangle's slowness
|
// initialize triangle's slowness
|
||||||
void InitEleSlowness();
|
void InitEleSlowness(double in_slow);
|
||||||
// calculate synthetic direct arrive time and fmm time
|
// calculate synthetic direct arrive time and fmm time
|
||||||
void CalculateSolution();
|
void CalculateSolution(double bkg_slow);
|
||||||
// set source parameters
|
// set source parameters
|
||||||
int set_init_source(double x,double y,double r,double s);
|
void set_init_source(const gctl::point2dc &loc);
|
||||||
private:
|
private:
|
||||||
int node_num_, ele_num_;
|
size_t node_num_, ele_num_, src_id_;
|
||||||
vector<vertex> nodes_;
|
vector<vertex> nodes_;
|
||||||
vector<ele> elements_;
|
vector<ele> elements_;
|
||||||
|
|
||||||
vector<vertex*> nodes_ptr_;
|
vector<vertex*> nodes_ptr_;
|
||||||
source init_source_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int FMM_2D_TRIANGLE::ReadFiles(char* filename)
|
int FMM_2D_TRIANGLE::ReadFiles(char* filename)
|
||||||
@ -152,14 +141,14 @@ int FMM_2D_TRIANGLE::ReadFiles(char* filename)
|
|||||||
clog << "reading node file:\t" << full_name;
|
clog << "reading node file:\t" << full_name;
|
||||||
|
|
||||||
getline(infile,temp_str);
|
getline(infile,temp_str);
|
||||||
temp_ss = gctl::str2ss(temp_str);
|
gctl::str2ss(temp_str, temp_ss);
|
||||||
temp_ss >> node_num_;
|
temp_ss >> node_num_;
|
||||||
|
|
||||||
nodes_.resize(node_num_);
|
nodes_.resize(node_num_);
|
||||||
for (int i = 0; i < node_num_; i++)
|
for (int i = 0; i < node_num_; i++)
|
||||||
{
|
{
|
||||||
getline(infile,temp_str);
|
getline(infile,temp_str);
|
||||||
temp_ss = gctl::str2ss(temp_str);
|
gctl::str2ss(temp_str, temp_ss);
|
||||||
temp_ss >> nodes_[i].id >> nodes_[i].x >> nodes_[i].y;
|
temp_ss >> nodes_[i].id >> nodes_[i].x >> nodes_[i].y;
|
||||||
}
|
}
|
||||||
infile.close();
|
infile.close();
|
||||||
@ -182,14 +171,14 @@ int FMM_2D_TRIANGLE::ReadFiles(char* filename)
|
|||||||
clog << "reading element file:\t" << full_name;
|
clog << "reading element file:\t" << full_name;
|
||||||
|
|
||||||
getline(infile,temp_str);
|
getline(infile,temp_str);
|
||||||
temp_ss = gctl::str2ss(temp_str);
|
gctl::str2ss(temp_str, temp_ss);
|
||||||
temp_ss >> ele_num_;
|
temp_ss >> ele_num_;
|
||||||
|
|
||||||
elements_.resize(ele_num_);
|
elements_.resize(ele_num_);
|
||||||
for (int i = 0; i < ele_num_; i++)
|
for (int i = 0; i < ele_num_; i++)
|
||||||
{
|
{
|
||||||
getline(infile,temp_str);
|
getline(infile,temp_str);
|
||||||
temp_ss = gctl::str2ss(temp_str);
|
gctl::str2ss(temp_str, temp_ss);
|
||||||
temp_ss >> elements_[i].id >> tmp_ids[0] >> tmp_ids[1] >> tmp_ids[2];
|
temp_ss >> elements_[i].id >> tmp_ids[0] >> tmp_ids[1] >> tmp_ids[2];
|
||||||
elements_[i].vec_ptr[0] = &nodes_[tmp_ids[0]];
|
elements_[i].vec_ptr[0] = &nodes_[tmp_ids[0]];
|
||||||
elements_[i].vec_ptr[1] = &nodes_[tmp_ids[1]];
|
elements_[i].vec_ptr[1] = &nodes_[tmp_ids[1]];
|
||||||
@ -201,7 +190,7 @@ int FMM_2D_TRIANGLE::ReadFiles(char* filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reorder the vertice sequence to anti-clockwise
|
// reorder the vertice sequence to anti-clockwise
|
||||||
gctl::point2d_c v01, v02;
|
gctl::point2dc v01, v02;
|
||||||
vertex *tmp_ptr;
|
vertex *tmp_ptr;
|
||||||
for (int i = 0; i < ele_num_; i++)
|
for (int i = 0; i < ele_num_; i++)
|
||||||
{
|
{
|
||||||
@ -226,7 +215,7 @@ int FMM_2D_TRIANGLE::ReadFiles(char* filename)
|
|||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
// opposite edge length of vertex j
|
// opposite edge length of vertex j
|
||||||
elements_[i].edge_l[j] = gctl::geometry2d::distance(elements_[i].vec_ptr[(j+1)%3], elements_[i].vec_ptr[(j+2)%3]);
|
elements_[i].edge_l[j] = gctl::distance(*elements_[i].vec_ptr[(j+1)%3], *elements_[i].vec_ptr[(j+2)%3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate triangle's area
|
// calculate triangle's area
|
||||||
@ -365,52 +354,32 @@ int FMM_2D_TRIANGLE::OutMsh(char* filename, bool tag)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FMM_2D_TRIANGLE::InitNodeSlowness(double default_slow)
|
|
||||||
{
|
|
||||||
// if no background slowness is given.
|
|
||||||
// set all node's slowness as the same as source's slowness.
|
|
||||||
if (default_slow == 0.0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < node_num_; i++)
|
|
||||||
{
|
|
||||||
nodes_[i].slow = init_source_.slow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < node_num_; i++)
|
|
||||||
{
|
|
||||||
nodes_[i].slow = default_slow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set slowness within a rectangular area.
|
// set slowness within a rectangular area.
|
||||||
void FMM_2D_TRIANGLE::SetRectangeSlowness(double ab_slow,double xmin,double xmax,double ymin,double ymax)
|
void FMM_2D_TRIANGLE::SetRectangeSlowness(double ab_slow,double xmin,double xmax,double ymin,double ymax)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < node_num_; i++)
|
gctl::point2dc cen;
|
||||||
|
for (int i = 0; i < ele_num_; i++)
|
||||||
{
|
{
|
||||||
if (nodes_[i].x >= xmin && nodes_[i].x <= xmax &&
|
cen = 1.0/3.0 * (*elements_[i].vec_ptr[0] + *elements_[i].vec_ptr[1] + *elements_[i].vec_ptr[2]);
|
||||||
nodes_[i].y >= ymin && nodes_[i].y <= ymax)
|
if (cen.x >= xmin && cen.x <= xmax && cen.y >= ymin && cen.y <= ymax)
|
||||||
{
|
{
|
||||||
nodes_[i].slow = ab_slow;
|
elements_[i].slow = ab_slow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set element's slowness as the mean value of three vertice's slowness.
|
// set element's slowness as the mean value of three vertice's slowness.
|
||||||
void FMM_2D_TRIANGLE::InitEleSlowness()
|
void FMM_2D_TRIANGLE::InitEleSlowness(double in_slow)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ele_num_; i++)
|
for (int i = 0; i < ele_num_; i++)
|
||||||
{
|
{
|
||||||
elements_[i].slow = (elements_[i].vec_ptr[0]->slow + elements_[i].vec_ptr[1]->slow + elements_[i].vec_ptr[2]->slow)/3.0;
|
elements_[i].slow = in_slow;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FMM_2D_TRIANGLE::CalculateSolution()
|
void FMM_2D_TRIANGLE::CalculateSolution(double bkg_slow)
|
||||||
{
|
{
|
||||||
time_t start_time, stop_time;
|
time_t start_time, stop_time;
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
@ -420,19 +389,7 @@ void FMM_2D_TRIANGLE::CalculateSolution()
|
|||||||
//this calculation is only valid for testing when there is no abnormal slowness or obstacles.
|
//this calculation is only valid for testing when there is no abnormal slowness or obstacles.
|
||||||
for (int i = 0; i < node_num_; i++)
|
for (int i = 0; i < node_num_; i++)
|
||||||
{
|
{
|
||||||
nodes_[i].syn_time = gctl::geometry2d::distance(&nodes_[i], &init_source_) * init_source_.slow;
|
nodes_[i].syn_time = gctl::distance(nodes_[i], nodes_[src_id_]) * bkg_slow;
|
||||||
}
|
|
||||||
|
|
||||||
//initialize source nodes and close nodes
|
|
||||||
//set a vertex's tag as 'active' if it is inside the initial radius
|
|
||||||
//and calculate node's time as direct arrival time
|
|
||||||
for (int i = 0; i < node_num_; i++)
|
|
||||||
{
|
|
||||||
if (gctl::geometry2d::distance(&nodes_[i], &init_source_) <= init_source_.rad)
|
|
||||||
{
|
|
||||||
nodes_[i].tag = 2;
|
|
||||||
nodes_[i].time = gctl::geometry2d::distance(&nodes_[i], &init_source_) * init_source_.slow;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//set all close vertice's tag to 'close' and add them to wave front list
|
//set all close vertice's tag to 'close' and add them to wave front list
|
||||||
@ -451,32 +408,18 @@ void FMM_2D_TRIANGLE::CalculateSolution()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//assign initial tags for elements
|
|
||||||
//set an element as calculated only if all its three vectice are activated.
|
|
||||||
for (int i = 0; i < ele_num_; i++)
|
|
||||||
{
|
|
||||||
if (elements_[i].vec_ptr[0]->tag == 2 &&
|
|
||||||
elements_[i].vec_ptr[1]->tag == 2 &&
|
|
||||||
elements_[i].vec_ptr[2]->tag == 2)
|
|
||||||
{
|
|
||||||
elements_[i].tag = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate trial time for all close nodes
|
//calculate trial time for all close nodes
|
||||||
for (int i = 0; i < nodes_ptr_.size(); i++)
|
for (int i = 0; i < nodes_ptr_.size(); i++)
|
||||||
{
|
{
|
||||||
local_update(nodes_ptr_[i]);
|
local_update(nodes_ptr_[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
gctl::heap_sort<vertex*> time_sorter;
|
|
||||||
//marching forward and updating the close nodes set
|
//marching forward and updating the close nodes set
|
||||||
while (!nodes_ptr_.empty())
|
while (!nodes_ptr_.empty())
|
||||||
{
|
{
|
||||||
// heap sort close nodes pointers to put a node at the first place if it has the smallest time
|
// heap sort close nodes pointers to put a node at the first place if it has the smallest time
|
||||||
time_sorter.execute(&nodes_ptr_, [](vector<vertex*> *a, int l_id, int r_id)->bool{
|
std::sort(nodes_ptr_.begin(), nodes_ptr_.end(), [](vertex *a, vertex *b)->bool{
|
||||||
if (a->at(l_id)->time < a->at(r_id)->time) return true;
|
if (a->time < b->time) return true; return false;
|
||||||
else return false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//change the first node's tag to 2 and update it's neighbor's time if it is not active (tag != 2)
|
//change the first node's tag to 2 and update it's neighbor's time if it is not active (tag != 2)
|
||||||
@ -507,19 +450,38 @@ void FMM_2D_TRIANGLE::CalculateSolution()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FMM_2D_TRIANGLE::set_init_source(double x, double y, double r, double s)
|
void FMM_2D_TRIANGLE::set_init_source(const gctl::point2dc &loc)
|
||||||
{
|
{
|
||||||
if (s <=0 || r <= 0)
|
// Find the closest node and make it the source
|
||||||
{
|
double dist, mini_dist = 1e+30;
|
||||||
cerr << "source initialization error!" << endl;
|
for (size_t i = 0; i < node_num_; i++)
|
||||||
return -1;
|
{
|
||||||
}
|
dist = gctl::distance(loc, nodes_[i]);
|
||||||
else
|
if (dist < mini_dist)
|
||||||
{
|
{
|
||||||
init_source_.x = x; init_source_.y = y;
|
mini_dist = dist;
|
||||||
init_source_.slow = s; init_source_.rad = r;
|
src_id_ = i;
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initiate the source time
|
||||||
|
nodes_[src_id_].time = 0.0;
|
||||||
|
nodes_[src_id_].tag = 2;
|
||||||
|
for (size_t i = 0; i < nodes_[src_id_].e_neigh.size(); i++)
|
||||||
|
{
|
||||||
|
nodes_[src_id_].e_neigh[i]->tag = 1;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
if (nodes_[src_id_].e_neigh[i]->vec_ptr[j]->id != src_id_)
|
||||||
|
{
|
||||||
|
dist = gctl::distance(nodes_[src_id_], *nodes_[src_id_].e_neigh[i]->vec_ptr[j]);
|
||||||
|
nodes_[src_id_].e_neigh[i]->vec_ptr[j]->time = nodes_[src_id_].e_neigh[i]->slow * dist;
|
||||||
|
nodes_[src_id_].e_neigh[i]->vec_ptr[j]->tag = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************main function here*****************************/
|
/*******************************************main function here*****************************/
|
||||||
@ -538,27 +500,28 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else if (!strcmp(argv[1],"calculate"))
|
else if (!strcmp(argv[1],"calculate"))
|
||||||
{
|
{
|
||||||
double s_x, s_y, s_rad, s_slow;
|
if(instance.ReadFiles(argv[2])) return 0;
|
||||||
if (4 != sscanf(argv[3], "%lf/%lf/%lf/%lf", &s_x, &s_y, &s_rad, &s_slow))
|
|
||||||
|
double s_x, s_y, s_slow;
|
||||||
|
if (3 != sscanf(argv[3], "%lf/%lf/%lf", &s_x, &s_y, &s_slow))
|
||||||
{
|
{
|
||||||
cerr << "wrong source parameter." << endl;
|
cerr << "wrong source parameter." << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
//set slowness here
|
||||||
if(instance.set_init_source(s_x, s_y, s_rad, s_slow)) return 0;
|
instance.InitEleSlowness(s_slow);
|
||||||
if(instance.ReadFiles(argv[2])) return 0;
|
instance.set_init_source(gctl::point2dc(s_x, s_y));
|
||||||
//set node slowness here
|
|
||||||
instance.InitNodeSlowness();
|
|
||||||
|
|
||||||
//add abnormal slowness
|
//add abnormal slowness
|
||||||
double ab_slow, ab_xmin, ab_xmax, ab_ymin, ab_ymax;
|
double ab_slow, ab_xmin, ab_xmax, ab_ymin, ab_ymax;
|
||||||
string all_ab_para, old_ab_para;
|
string all_ab_para, old_ab_para;
|
||||||
string tmp_str;
|
string tmp_str;
|
||||||
|
stringstream tmp_ss;
|
||||||
if (argc >= 5)
|
if (argc >= 5)
|
||||||
{
|
{
|
||||||
old_ab_para = argv[4];
|
old_ab_para = argv[4];
|
||||||
gctl::replace_all(all_ab_para, old_ab_para, ",", " ");
|
gctl::replace_all(all_ab_para, old_ab_para, ",", " ");
|
||||||
stringstream tmp_ss = gctl::str2ss(all_ab_para);
|
gctl::str2ss(all_ab_para, tmp_ss);
|
||||||
while (tmp_ss >> tmp_str)
|
while (tmp_ss >> tmp_str)
|
||||||
{
|
{
|
||||||
if (5 != sscanf(tmp_str.c_str(), "%lf/%lf/%lf/%lf/%lf",
|
if (5 != sscanf(tmp_str.c_str(), "%lf/%lf/%lf/%lf/%lf",
|
||||||
@ -571,9 +534,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set element slowness here
|
instance.CalculateSolution(s_slow);
|
||||||
instance.InitEleSlowness();
|
|
||||||
instance.CalculateSolution();
|
|
||||||
if(instance.OutMsh(argv[2],true)) return 0;
|
if(instance.OutMsh(argv[2],true)) return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user